* [edk2-platform patch 0/7] Add Initial QSP MinPlatform Pkg for SIMICS
@ 2019-08-09 22:46 David Wei
2019-08-09 22:46 ` [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
` (6 more replies)
0 siblings, 7 replies; 37+ messages in thread
From: David Wei @ 2019-08-09 22:46 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.
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 for SIMICS QSP Platform
SimicsOpenBoardPkg: 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 +++
.../Library/LoadLinuxLib/Linux.c | 662 ++++++++
.../Library/LoadLinuxLib/LinuxGdt.c | 175 +++
.../Library/NvVarsFileLib/FsAccess.c | 507 +++++++
.../Library/NvVarsFileLib/NvVarsFileLib.c | 77 +
.../SerializeVariablesLib/SerializeVariablesLib.c | 869 +++++++++++
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++
.../Library/PlatformBootManagerLib/BdsPlatform.c | 1553 +++++++++++++++++++
.../Library/PlatformBootManagerLib/PlatformData.c | 35 +
.../Overrides/MdeModulePkg/Logo/Logo.c | 154 ++
.../MdePkg/Library/BasePciLibCf8/PciLib.c | 1221 +++++++++++++++
.../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 | 417 ++++++
.../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++
.../8259InterruptControllerDxe/8259.c | 622 ++++++++
.../SimicsOpenBoardPkg/PlatformDxe/Platform.c | 865 +++++++++++
.../PlatformDxe/PlatformConfig.c | 123 ++
.../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c | 57 +
.../PlatformPei/FeatureControl.c | 114 ++
Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c | 100 ++
.../SimicsOpenBoardPkg/PlatformPei/MemDetect.c | 568 +++++++
.../SimicsOpenBoardPkg/PlatformPei/Platform.c | 631 ++++++++
.../SiliconPolicyInitLib/SiliconPolicyInitLib.c | 108 ++
.../SiliconPolicyUpdateLib.c | 70 +
.../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 +++
.../Override/UefiCpuPkg/SecCore/SecMain.c | 956 ++++++++++++
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c | 148 ++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c | 353 +++++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.c | 199 +++
.../SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf | 31 +
.../Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl | 821 ++++++++++
.../Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h | 75 +
.../BoardX58ICH10/DecomprScratchEnd.fdf.inc | 66 +
.../BoardX58ICH10/GitEdk2X58ICH10.bat | 75 +
.../BoardInitLib/PeiBoardInitPostMemLib.inf | 36 +
.../Library/BoardInitLib/PeiBoardInitPreMemLib.inf | 38 +
.../Library/BoardInitLib/PeiX58ICH10InitLib.h | 16 +
.../BoardX58ICH10/PlatformPkgBuildOption.dsc | 89 ++
.../BoardX58ICH10/PlatformPkgConfig.dsc | 56 +
.../BoardX58ICH10/PlatformPkgPcd.dsc | 283 ++++
.../BoardX58ICH10/SimicsX58Pkg.fdf.inc | 48 +
.../BoardX58ICH10/SimicsX58PkgIa32X64.dsc | 244 +++
.../BoardX58ICH10/SimicsX58PkgIa32X64.fdf | 303 ++++
.../BoardX58ICH10/VarStore.fdf.inc | 53 +
.../Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat | 139 ++
.../BoardX58ICH10/build_config.cfg | 31 +
.../SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat | 198 +++
.../Include/Guid/SimicsX58PlatformConfig.h | 17 +
.../Include/IndustryStandard/X58Ich10.h | 106 ++
.../SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h | 298 ++++
.../SimicsOpenBoardPkg/Include/Protocol/IsaIo.h | 356 +++++
.../Include/Protocol/Legacy8259.h | 291 ++++
.../Include/Register/X58SmramSaveStateMap.h | 178 +++
.../SimicsOpenBoardPkg/Include/SimicsPlatforms.h | 54 +
.../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/LoadLinuxLib/Ia32/JumpToKernel.nasm | 41 +
.../Library/LoadLinuxLib/LoadLinuxLib.h | 52 +
.../Library/LoadLinuxLib/LoadLinuxLib.inf | 42 +
.../Library/LoadLinuxLib/X64/JumpToKernel.nasm | 85 ++
.../Library/NvVarsFileLib/NvVarsFileLib.h | 55 +
.../Library/NvVarsFileLib/NvVarsFileLib.inf | 53 +
.../SerializeVariablesLib/SerializeVariablesLib.h | 33 +
.../SerializeVariablesLib.inf | 36 +
.../Library/PciHostBridgeLib/PciHostBridge.h | 68 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 50 +
.../Library/PlatformBootManagerLib/BdsPlatform.h | 156 ++
.../PlatformBootManagerLib.inf | 69 +
.../Overrides/MdeModulePkg/Logo/Logo.bmp | Bin 0 -> 141078 bytes
.../Overrides/MdeModulePkg/Logo/Logo.idf | 10 +
.../Overrides/MdeModulePkg/Logo/Logo.inf | 28 +
.../Overrides/MdeModulePkg/Logo/Logo.uni | 16 +
.../Overrides/MdeModulePkg/Logo/LogoDxe.inf | 55 +
.../Overrides/MdeModulePkg/Logo/LogoDxe.uni | 16 +
.../Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni | 14 +
.../Overrides/MdeModulePkg/Logo/LogoExtra.uni | 14 +
.../Library/BasePciLibCf8/DxePciLibX58Ich10.inf | 40 +
.../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 +
.../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++
.../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++
.../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 73 +
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 281 ++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 +
.../8259InterruptControllerDxe/8259.h | 218 +++
.../8259InterruptControllerDxe/8259.inf | 46 +
.../8259InterruptControllerDxe/Legacy8259.uni | 16 +
.../8259InterruptControllerDxe/Legacy8259Extra.uni | 14 +
.../SimicsOpenBoardPkg/PlatformDxe/Platform.h | 37 +
.../SimicsOpenBoardPkg/PlatformDxe/Platform.inf | 65 +
.../SimicsOpenBoardPkg/PlatformDxe/Platform.uni | 31 +
.../PlatformDxe/PlatformConfig.h | 51 +
.../PlatformDxe/PlatformForms.vfr | 67 +
.../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h | 50 +
.../SimicsOpenBoardPkg/PlatformPei/Platform.h | 93 ++
.../SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf | 109 ++
.../SiliconPolicyInitLib/SiliconPolicyInitLib.inf | 38 +
.../SiliconPolicyUpdateLib.inf | 35 +
.../SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec | 168 +++
.../SmbiosPlatformDxe/SmbiosPlatformDxe.h | 38 +
.../SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 51 +
Platform/Intel/build.cfg | 2 +
Silicon/Intel/SimicsICH10Pkg/ICH10Pkg.dec | 22 +
.../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 ++++
.../IncludePrivate/Library/PchSpiCommonLib.h | 396 +++++
.../Library/ResetSystemLib/ResetSystemLib.inf | 34 +
.../SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf | 52 +
.../BasePchSpiCommonLib/BasePchSpiCommonLib.inf | 33 +
Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc | 12 +
.../Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf | 9 +
.../Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf | 9 +
.../Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf | 13 +
.../SmmControl/RuntimeDxe/SmmControl2Dxe.inf | 59 +
Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpi.h | 23 +
Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpiSmm.inf | 44 +
.../Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm | 45 +
.../Override/UefiCpuPkg/SecCore/SecMain.inf | 71 +
.../Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm | 45 +
Silicon/Intel/SimicsX58SktPkg/SktPei.dsc | 18 +
.../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf | 9 +
.../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf | 10 +
Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf | 17 +
.../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf | 16 +
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf | 52 +
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf | 64 +
.../SimicsX58SktPkg/Smm/Access/SmramInternal.h | 81 +
158 files changed, 29753 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/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/SerializeVariablesLib/SerializeVariablesLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.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/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/Override/UefiCpuPkg/SecCore/SecMain.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/GitEdk2X58ICH10.bat
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/PlatformPkgBuildOption.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58Pkg.fdf.inc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.fdf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/VarStore.fdf.inc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.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/LoadLinuxLib/Ia32/JumpToKernel.nasm
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
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/SerializeVariablesLib/SerializeVariablesLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.bmp
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.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/SimicsOpenBoardPkg.dec
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/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/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/PchCommonLib.dsc
create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
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/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPei.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] 37+ messages in thread
* [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
2019-08-09 22:46 [edk2-platform patch 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
@ 2019-08-09 22:46 ` David Wei
2019-08-15 8:34 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10 David Wei
` (5 subsequent siblings)
6 siblings, 2 replies; 37+ messages in thread
From: David Wei @ 2019-08-09 22:46 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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../Override/UefiCpuPkg/SecCore/SecMain.c | 956 +++++++++++++++++++++
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c | 148 ++++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c | 353 ++++++++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.c | 199 +++++
.../Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm | 45 +
.../Override/UefiCpuPkg/SecCore/SecMain.inf | 71 ++
.../Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm | 45 +
Silicon/Intel/SimicsX58SktPkg/SktPei.dsc | 18 +
.../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf | 9 +
.../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf | 10 +
Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf | 17 +
.../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf | 16 +
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf | 52 ++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf | 64 ++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.h | 81 ++
15 files changed, 2084 insertions(+)
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.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 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPei.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/Override/UefiCpuPkg/SecCore/SecMain.c b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
new file mode 100644
index 0000000000..c52d459ef2
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/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 <IndustryStandard/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_INFO, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32 (PcdSimicsDxeMemFvBase)));
+ DEBUG ((EFI_D_INFO, "OutputBuffer: 0x%x\n", OutputBuffer));
+ DEBUG ((EFI_D_INFO, "OutputBufferSize: 0x%x\n", OutputBufferSize));
+ DEBUG ((EFI_D_INFO, "ScratchBuffer: 0x%x\n", ScratchBuffer));
+ DEBUG ((EFI_D_INFO, "ScratchBufferSize: 0x%x\n", ScratchBufferSize));
+ DEBUG ((EFI_D_INFO, "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_ERROR, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "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/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..d07d88142a
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
@@ -0,0 +1,353 @@
+/** @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, 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 <SimicsPlatforms.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 QEMU 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 QEMU.
+ //
+
+ TopOfLowRam = GetSystemMemorySizeBelow4gb ();
+ ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) == 0);
+ TopOfLowRamMb = TopOfLowRam >> 20;
+ DEBUG((EFI_D_ERROR, "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_ERROR, "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_ERROR, "MCH_TSEGMB =0x%x; \n", PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
+ DEBUG((EFI_D_ERROR, "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..898fc25084
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
@@ -0,0 +1,199 @@
+/** @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 <Guid/AcpiS3Context.h>
+#include <IndustryStandard/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/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm
new file mode 100644
index 0000000000..19ffb6f86d
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm
@@ -0,0 +1,45 @@
+; @file
+; Copyright (c) 2006 - 2013 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/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
new file mode 100644
index 0000000000..ac993ac1ce
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
@@ -0,0 +1,71 @@
+## @file
+# SEC Driver
+#
+# Copyright (c) 2008 - 2018 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ BaseMemoryLib
+ PeiServicesLib
+ PcdLib
+ UefiCpuLib
+ DebugAgentLib
+ IoLib
+ PeCoffLib
+ PeCoffGetEntryPointLib
+ PeCoffExtraActionLib
+ ExtractGuidedSectionLib
+ LocalApicLib
+ PciCf8Lib
+
+[Ppis]
+ gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
+ gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+ gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+
+[FeaturePcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm
new file mode 100644
index 0000000000..0eb86ec2ca
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm
@@ -0,0 +1,45 @@
+; @file
+; Copyright (c) 2006 - 2013 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/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
new file mode 100644
index 0000000000..0be8be4966
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
@@ -0,0 +1,18 @@
+## @file
+# Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+ #
+ # SEC Phase modules
+ #
+ $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ }
+ 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..78eca21a43
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 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..9f037e99d4
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
@@ -0,0 +1,10 @@
+## @file
+# Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 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..596d633cd3
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
@@ -0,0 +1,17 @@
+## @file
+# Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 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_SECMAIN USE = IA32 $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf
+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..9004b9cb83
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
@@ -0,0 +1,16 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#INF $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuArchDxe/CpuArchDxe.inf
+#INF $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuMpDxe/CpuMpDxe.inf
+!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..2f630b4b95
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
@@ -0,0 +1,52 @@
+## @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.
+#
+# 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..1d3b028c85
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
@@ -0,0 +1,64 @@
+## @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.
+#
+# 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+ OvmfPkg/OvmfPkg.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] 37+ messages in thread
* [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10
2019-08-09 22:46 [edk2-platform patch 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
2019-08-09 22:46 ` [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
@ 2019-08-09 22:46 ` David Wei
2019-08-13 2:01 ` Nate DeSimone
` (2 more replies)
2019-08-09 22:46 ` [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules David Wei
` (4 subsequent siblings)
6 siblings, 3 replies; 37+ messages in thread
From: David Wei @ 2019-08-09 22:46 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>
Contributed-under: TianoCore Contribution Agreement 1.0
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 | 22 +
.../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 +++++++
.../IncludePrivate/Library/PchSpiCommonLib.h | 396 +++++++++
.../Library/ResetSystemLib/ResetSystemLib.inf | 34 +
.../SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf | 52 ++
.../BasePchSpiCommonLib/BasePchSpiCommonLib.inf | 33 +
Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc | 12 +
.../Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf | 9 +
.../Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf | 9 +
.../Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf | 13 +
.../SmmControl/RuntimeDxe/SmmControl2Dxe.inf | 59 ++
Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpi.h | 23 +
Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpiSmm.inf | 44 +
25 files changed, 4152 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/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/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/PchCommonLib.dsc
create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
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..46355e191c
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,137 @@
+/** @file
+ Reset System Library functions for OVMF
+
+ Copyright (c) 2006 - 2016 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 <IndustryStandard/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..3d4e24eac6
--- /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) 2017 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..1e5cd0d744
--- /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) 2017 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..77fb76d7cd
--- /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) 2017 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 <IndustryStandard/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..8fb4947b1a
--- /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 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/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..19eb469657
--- /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) 2017 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..f9d340d6df
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/ICH10Pkg.dec
@@ -0,0 +1,22 @@
+## @file
+# Copyright (c) 2014 - 2016 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}}
diff --git a/Silicon/Intel/SimicsICH10Pkg/Include/Library/SpiFlashCommonLib.h b/Silicon/Intel/SimicsICH10Pkg/Include/Library/SpiFlashCommonLib.h
new file mode 100644
index 0000000000..c36360bcb0
--- /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) 2017 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..552ce28d8c
--- /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) 2017 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..d503d130c8
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/Include/PchLimits.h
@@ -0,0 +1,94 @@
+/** @file
+ Build time limits of PCH resources.
+
+ Copyright (c) 2017 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..00139fc230
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/Include/PchReservedResources.h
@@ -0,0 +1,60 @@
+/** @file
+ PCH preserved MMIO resource definitions.
+
+ Copyright (c) 2017 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..cb5f26c47b
--- /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) 2017 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..e08721f405
--- /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) 2017 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..a727aae927
--- /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) 2017 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/IncludePrivate/Library/PchSpiCommonLib.h b/Silicon/Intel/SimicsICH10Pkg/IncludePrivate/Library/PchSpiCommonLib.h
new file mode 100644
index 0000000000..5bdec96197
--- /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) 2017 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..4af462da47
--- /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 - 2018 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..b5c97f1930
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
@@ -0,0 +1,52 @@
+## @file
+# SMM Library instance of Spi Flash Common Library Class
+#
+# Copyright (c) 2017 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
+ MinPlatformPkg/MinPlatformPkg.dec
+
+
+[Pcd]
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.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..11c832e487
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Component description file for the PchSpiCommonLib
+#
+# Copyright (c) 2017 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+
+[LibraryClasses]
+ IoLib
+ DebugLib
+
+[Pcd]
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
diff --git a/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc b/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
new file mode 100644
index 0000000000..a2d006ee35
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
@@ -0,0 +1,12 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE libraries.
+#
+# Copyright (c) 2017 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/PchPostMemoryInclude.fdf b/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
new file mode 100644
index 0000000000..78eca21a43
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf b/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
new file mode 100644
index 0000000000..2d3a127c20
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf b/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
new file mode 100644
index 0000000000..d079c593d9
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
@@ -0,0 +1,13 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 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/SmmControl/RuntimeDxe/SmmControl2Dxe.inf b/Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
new file mode 100644
index 0000000000..e23dd9f2fe
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
@@ -0,0 +1,59 @@
+## @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.
+#
+# 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..f7fdd3abbe
--- /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) 2017 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..265af00ac0
--- /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) 2017 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] 37+ messages in thread
* [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
2019-08-09 22:46 [edk2-platform patch 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
2019-08-09 22:46 ` [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
2019-08-09 22:46 ` [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10 David Wei
@ 2019-08-09 22:46 ` David Wei
2019-08-15 18:35 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio David Wei
` (3 subsequent siblings)
6 siblings, 2 replies; 37+ messages in thread
From: David Wei @ 2019-08-09 22:46 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, PlatformDxe, PlatformPei, Policy, SmbiosPlatformDxe
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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../Library/LoadLinuxLib/Linux.c | 662 ++++++++++++++++
.../Library/LoadLinuxLib/LinuxGdt.c | 175 +++++
.../Library/NvVarsFileLib/FsAccess.c | 507 ++++++++++++
.../Library/NvVarsFileLib/NvVarsFileLib.c | 77 ++
.../SerializeVariablesLib/SerializeVariablesLib.c | 869 +++++++++++++++++++++
.../SimicsOpenBoardPkg/PlatformDxe/Platform.c | 865 ++++++++++++++++++++
.../PlatformDxe/PlatformConfig.c | 123 +++
.../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c | 57 ++
.../PlatformPei/FeatureControl.c | 114 +++
Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c | 100 +++
.../SimicsOpenBoardPkg/PlatformPei/MemDetect.c | 568 ++++++++++++++
.../SimicsOpenBoardPkg/PlatformPei/Platform.c | 631 +++++++++++++++
.../SiliconPolicyInitLib/SiliconPolicyInitLib.c | 108 +++
.../SiliconPolicyUpdateLib.c | 70 ++
.../SmbiosPlatformDxe/SmbiosPlatformDxe.c | 148 ++++
.../SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf | 31 +
.../Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl | 821 +++++++++++++++++++
.../Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h | 75 ++
.../Include/Guid/SimicsX58PlatformConfig.h | 17 +
.../Include/IndustryStandard/X58Ich10.h | 106 +++
.../SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h | 298 +++++++
.../SimicsOpenBoardPkg/Include/Protocol/IsaIo.h | 356 +++++++++
.../Include/Protocol/Legacy8259.h | 291 +++++++
.../Include/Register/X58SmramSaveStateMap.h | 178 +++++
.../SimicsOpenBoardPkg/Include/SimicsPlatforms.h | 54 ++
.../Library/LoadLinuxLib/Ia32/JumpToKernel.nasm | 41 +
.../Library/LoadLinuxLib/LoadLinuxLib.h | 52 ++
.../Library/LoadLinuxLib/LoadLinuxLib.inf | 42 +
.../Library/LoadLinuxLib/X64/JumpToKernel.nasm | 85 ++
.../Library/NvVarsFileLib/NvVarsFileLib.h | 55 ++
.../Library/NvVarsFileLib/NvVarsFileLib.inf | 53 ++
.../SerializeVariablesLib/SerializeVariablesLib.h | 33 +
.../SerializeVariablesLib.inf | 36 +
.../SimicsOpenBoardPkg/PlatformDxe/Platform.h | 37 +
.../SimicsOpenBoardPkg/PlatformDxe/Platform.inf | 65 ++
.../SimicsOpenBoardPkg/PlatformDxe/Platform.uni | 31 +
.../PlatformDxe/PlatformConfig.h | 51 ++
.../PlatformDxe/PlatformForms.vfr | 67 ++
.../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h | 50 ++
.../SimicsOpenBoardPkg/PlatformPei/Platform.h | 93 +++
.../SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf | 109 +++
.../SiliconPolicyInitLib/SiliconPolicyInitLib.inf | 38 +
.../SiliconPolicyUpdateLib.inf | 35 +
.../SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec | 168 ++++
.../SmbiosPlatformDxe/SmbiosPlatformDxe.h | 38 +
.../SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 51 ++
46 files changed, 8531 insertions(+)
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/SerializeVariablesLib/SerializeVariablesLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.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/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/SimicsX58PlatformConfig.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
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/LoadLinuxLib.inf
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/SerializeVariablesLib/SerializeVariablesLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.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/SimicsOpenBoardPkg.dec
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/LoadLinuxLib/Linux.c b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
new file mode 100644
index 0000000000..43a2dee9f6
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
@@ -0,0 +1,662 @@
+/** @file
+ Copyright (c) 2011 - 2014 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..624fbc37cb
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
@@ -0,0 +1,175 @@
+/** @file
+ Initialize GDT for Linux.
+
+ Copyright (c) 2006 - 2012 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..6ba8784cf3
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
@@ -0,0 +1,507 @@
+/** @file
+ File System Access for NvVarsFileLib
+
+ Copyright (c) 2004 - 2014 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..f60fbc6112
--- /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) 2009 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/SerializeVariablesLib/SerializeVariablesLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
new file mode 100644
index 0000000000..c32a978550
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
@@ -0,0 +1,869 @@
+/** @file
+ Serialize Variables Library implementation
+
+ Copyright (c) 2004 - 2011 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/PlatformDxe/Platform.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
new file mode 100644
index 0000000000..7bede1496d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
@@ -0,0 +1,865 @@
+/** @file
+ This driver effectuates OVMF's 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/SimicsX58PlatformConfig.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 PlatformDxeStrings[];
+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, &gSimicsX58PlatformConfigGuid,
+ 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
+ PlatformDxeStrings, // 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/PlatformDxe/PlatformConfig.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
new file mode 100644
index 0000000000..b3b2b34064
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
@@ -0,0 +1,123 @@
+/** @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
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/SimicsX58PlatformConfig.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, &gSimicsX58PlatformConfigGuid,
+ 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, &gSimicsX58PlatformConfigGuid, &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/PlatformPei/Cmos.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
new file mode 100644
index 0000000000..fa2c22116c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
@@ -0,0 +1,57 @@
+/** @file
+ PC/AT CMOS access routines
+
+ Copyright (c) 2006 - 2009 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/PlatformPei/FeatureControl.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
new file mode 100644
index 0000000000..692405e417
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/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/PlatformPei/Fv.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
new file mode 100644
index 0000000000..818d135c95
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
@@ -0,0 +1,100 @@
+/** @file
+ Build FV related hobs for platform.
+
+ Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PiPei.h"
+#include "Platform.h"
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+
+
+/**
+ 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/PlatformPei/MemDetect.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
new file mode 100644
index 0000000000..4c527baef2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
@@ -0,0 +1,568 @@
+/** @file
+ Memory Detection for Virtual Machines.
+
+ Copyright (c) 2006 - 2016 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/PlatformPei/Platform.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
new file mode 100644
index 0000000000..e64bdc7c56
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
@@ -0,0 +1,631 @@
+/** @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 ();
+ }
+ PeiFvInitialization ();
+ MemMapInitialization ();
+ }
+
+ MiscInitialization ();
+ InstallFeatureControlCallback ();
+
+ return EFI_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..01a9ed40d5
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c
@@ -0,0 +1,108 @@
+/** @file
+ Copyright (c) 2018 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..6d9da67975
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c
@@ -0,0 +1,70 @@
+/** @file
+ Copyright (c) 2018 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/SmbiosPlatformDxe/SmbiosPlatformDxe.c b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
new file mode 100644
index 0000000000..82a2d60959
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
@@ -0,0 +1,148 @@
+/** @file
+ This driver installs SMBIOS information for OVMF
+
+ 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 OVMF
+
+ @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..839626eb86
--- /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 - 2018 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..76a8fbc081
--- /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) 2008 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF ", 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..6395ec11e2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
@@ -0,0 +1,75 @@
+/** @file
+ Platform specific defines for constructing ACPI tables
+
+ Copyright (c) 2013 - 2008 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _Platform_h_INCLUDED_
+#define _Platform_h_INCLUDED_
+
+#include <PiDxe.h>
+#include <IndustryStandard/Acpi.h>
+
+//
+// ACPI table information used to initialize tables.
+//
+#define EFI_ACPI_OEM_ID 'O','V','M','F',' ',' ' // OEMID 6 bytes long
+#define EFI_ACPI_OEM_TABLE_ID SIGNATURE_64('O','V','M','F','E','D','K','2') // OEM table id 8 bytes long
+#define EFI_ACPI_OEM_REVISION 0x02000820
+#define EFI_ACPI_CREATOR_ID SIGNATURE_32('O','V','M','F')
+#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/SimicsX58PlatformConfig.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.h
new file mode 100644
index 0000000000..f65f61d74d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.h
@@ -0,0 +1,17 @@
+/** @file
+ GUID for UEFI variables that are specific to OVMF configuration.
+
+ Copyright (C) 2014, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SIMICSX58_PLATFORM_CONFIG_H__
+#define __SIMICSX58_PLATFORM_CONFIG_H__
+
+#define SIMICSX58_PLATFORM_CONFIG_GUID \
+{0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
+
+extern EFI_GUID gSimicsX58PlatformConfigGuid;
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
new file mode 100644
index 0000000000..36c08176d1
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
@@ -0,0 +1,106 @@
+/** @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>
+
+//
+// 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/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
new file mode 100644
index 0000000000..12aeb1227c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
@@ -0,0 +1,298 @@
+/** @file
+ EFI ISA ACPI Protocol is used to enumerate and manage all the ISA controllers on
+ the platform's ISA Bus.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __ISA_ACPI_H_
+#define __ISA_ACPI_H_
+
+///
+/// Global ID for the EFI ISA ACPI Protocol.
+///
+#define EFI_ISA_ACPI_PROTOCOL_GUID \
+ { \
+ 0x64a892dc, 0x5561, 0x4536, { 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55 } \
+ }
+
+///
+/// Forward declaration fo the EFI ISA ACPI Protocol
+///
+typedef struct _EFI_ISA_ACPI_PROTOCOL EFI_ISA_ACPI_PROTOCOL;
+
+///
+/// ISA ACPI Protocol interrupt resource attributes.
+///
+#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_EDGE_SENSITIVE 0x01 ///< Edge triggered interrupt on a rising edge.
+#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_EDGE_SENSITIVE 0x02 ///< Edge triggered interrupt on a falling edge.
+#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_LEVEL_SENSITIVE 0x04 ///< Level sensitive interrupt active high.
+#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_LEVEL_SENSITIVE 0x08 ///< Level sensitive interrupt active low.
+
+///
+/// ISA ACPI Protocol DMA resource attributes.
+///
+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_MASK 0x03 ///< Bit mask of supported DMA speed attributes.
+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_COMPATIBILITY 0x00 ///< ISA controller supports compatibility mode DMA transfers.
+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_A 0x01 ///< ISA controller supports type A DMA transfers.
+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_B 0x02 ///< ISA controller supports type B DMA transfers.
+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_F 0x03 ///< ISA controller supports type F DMA transfers.
+#define EFI_ISA_ACPI_DMA_COUNT_BY_BYTE 0x04 ///< ISA controller increments DMA address by bytes (8-bit).
+#define EFI_ISA_ACPI_DMA_COUNT_BY_WORD 0x08 ///< ISA controller increments DMA address by words (16-bit).
+#define EFI_ISA_ACPI_DMA_BUS_MASTER 0x10 ///< ISA controller is a DMA bus master.
+#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT 0x20 ///< ISA controller only supports 8-bit DMA transfers.
+#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT_AND_16_BIT 0x40 ///< ISA controller both 8-bit and 16-bit DMA transfers.
+#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_16_BIT 0x80 ///< ISA controller only supports 16-bit DMA transfers.
+
+///
+/// ISA ACPI Protocol MMIO resource attributes
+///
+#define EFI_ISA_ACPI_MEMORY_WIDTH_MASK 0x03 ///< Bit mask of supported ISA memory width attributes.
+#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT 0x00 ///< ISA MMIO region only supports 8-bit access.
+#define EFI_ISA_ACPI_MEMORY_WIDTH_16_BIT 0x01 ///< ISA MMIO region only supports 16-bit access.
+#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT_AND_16_BIT 0x02 ///< ISA MMIO region supports both 8-bit and 16-bit access.
+#define EFI_ISA_ACPI_MEMORY_WRITEABLE 0x04 ///< ISA MMIO region supports write transactions.
+#define EFI_ISA_ACPI_MEMORY_CACHEABLE 0x08 ///< ISA MMIO region supports being cached.
+#define EFI_ISA_ACPI_MEMORY_SHADOWABLE 0x10 ///< ISA MMIO region may be shadowed.
+#define EFI_ISA_ACPI_MEMORY_EXPANSION_ROM 0x20 ///< ISA MMIO region is an expansion ROM.
+
+///
+/// ISA ACPI Protocol I/O resource attributes
+///
+#define EFI_ISA_ACPI_IO_DECODE_10_BITS 0x01 ///< ISA controllers uses a 10-bit address decoder for I/O cycles.
+#define EFI_ISA_ACPI_IO_DECODE_16_BITS 0x02 ///< ISA controllers uses a 16-bit address decoder for I/O cycles.
+
+///
+/// EFI ISA ACPI resource type
+///
+typedef enum {
+ EfiIsaAcpiResourceEndOfList, ///< Marks the end if a resource list.
+ EfiIsaAcpiResourceIo, ///< ISA I/O port resource range.
+ EfiIsaAcpiResourceMemory, ///< ISA MMIO resource range.
+ EfiIsaAcpiResourceDma, ///< ISA DMA resource.
+ EfiIsaAcpiResourceInterrupt ///< ISA interrupt resource.
+} EFI_ISA_ACPI_RESOURCE_TYPE;
+
+///
+/// EFI ISA ACPI generic resource structure
+///
+typedef struct {
+ EFI_ISA_ACPI_RESOURCE_TYPE Type; ///< The type of resource (I/O, MMIO, DMA, Interrupt).
+ UINT32 Attribute; ///< Bit mask of attributes associated with this resource. See EFI_ISA_ACPI_xxx macros for valid combinations.
+ UINT32 StartRange; ///< The start of the resource range.
+ UINT32 EndRange; ///< The end of the resource range.
+} EFI_ISA_ACPI_RESOURCE;
+
+///
+/// EFI ISA ACPI resource device identifier
+///
+typedef struct {
+ UINT32 HID; ///< The ACPI Hardware Identifier value associated with an ISA controller. Matchs ACPI DSDT contents.
+ UINT32 UID; ///< The ACPI Unique Identifier value associated with an ISA controller. Matches ACPI DSDT contents.
+} EFI_ISA_ACPI_DEVICE_ID;
+
+///
+/// EFI ISA ACPI resource list
+///
+typedef struct {
+ EFI_ISA_ACPI_DEVICE_ID Device; ///< The ACPI HID/UID associated with an ISA controller.
+ EFI_ISA_ACPI_RESOURCE *ResourceItem; ///< A pointer to the list of resources associated with an ISA controller.
+} EFI_ISA_ACPI_RESOURCE_LIST;
+
+/**
+ Enumerates the ISA controllers on an ISA bus.
+
+ This service allows all the ISA controllers on an ISA bus to be enumerated. If
+ Device is a pointer to a NULL value, then the first ISA controller on the ISA
+ bus is returned in Device and EFI_SUCCESS is returned. If Device is a pointer
+ to a value that was returned on a prior call to DeviceEnumerate(), then the next
+ ISA controller on the ISA bus is returned in Device and EFI_SUCCESS is returned.
+ If Device is a pointer to the last ISA controller on the ISA bus, then
+ EFI_NOT_FOUND is returned.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[out] Device The pointer to an ISA controller named by ACPI HID/UID.
+
+ @retval EFI_SUCCESS The next ISA controller on the ISA bus was returned.
+ @retval EFI_NOT_FOUND No device found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_DEVICE_ENUMERATE)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ OUT EFI_ISA_ACPI_DEVICE_ID **Device
+ );
+
+/**
+ Sets the power state of an ISA controller.
+
+ This services sets the power state of the ISA controller specified by Device to
+ the power state specified by OnOff. TRUE denotes on, FALSE denotes off.
+ If the power state is sucessfully set on the ISA Controller, then
+ EFI_SUCCESS is returned.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
+ @param[in] OnOff TRUE denotes on, FALSE denotes off.
+
+ @retval EFI_SUCCESS Successfully set the power state of the ISA controller.
+ @retval Other The ISA controller could not be placed in the requested power state.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_SET_DEVICE_POWER)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ IN EFI_ISA_ACPI_DEVICE_ID *Device,
+ IN BOOLEAN OnOff
+ );
+
+/**
+ Retrieves the current set of resources associated with an ISA controller.
+
+ Retrieves the set of I/O, MMIO, DMA, and interrupt resources currently
+ assigned to the ISA controller specified by Device. These resources
+ are returned in ResourceList.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
+ @param[out] ResourceList The pointer to the current resource list for Device.
+
+ @retval EFI_SUCCESS Successfully retrieved the current resource list.
+ @retval EFI_NOT_FOUND The resource list could not be retrieved.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_GET_CUR_RESOURCE)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ IN EFI_ISA_ACPI_DEVICE_ID *Device,
+ OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
+ );
+
+/**
+ Retrieves the set of possible resources that may be assigned to an ISA controller
+ with SetResource().
+
+ Retrieves the possible sets of I/O, MMIO, DMA, and interrupt resources for the
+ ISA controller specified by Device. The sets are returned in ResourceList.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
+ @param[out] ResourceList The pointer to the returned list of resource lists.
+
+ @retval EFI_UNSUPPORTED This service is not supported.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_GET_POS_RESOURCE)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ IN EFI_ISA_ACPI_DEVICE_ID *Device,
+ OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
+ );
+
+/**
+ Assigns resources to an ISA controller.
+
+ Assigns the I/O, MMIO, DMA, and interrupt resources specified by ResourceList
+ to the ISA controller specified by Device. ResourceList must match a resource list returned by GetPosResource() for the same ISA controller.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
+ @param[in] ResourceList The pointer to a resources list that must be one of the
+ resource lists returned by GetPosResource() for the
+ ISA controller specified by Device.
+
+ @retval EFI_SUCCESS Successfully set resources on the ISA controller.
+ @retval Other The resources could not be set for the ISA controller.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_SET_RESOURCE)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ IN EFI_ISA_ACPI_DEVICE_ID *Device,
+ IN EFI_ISA_ACPI_RESOURCE_LIST *ResourceList
+ );
+
+/**
+ Enables or disables an ISA controller.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[in] Device The pointer to the ISA controller to enable/disable.
+ @param[in] Enable TRUE to enable the ISA controller. FALSE to disable the
+ ISA controller.
+
+ @retval EFI_SUCCESS Successfully enabled/disabled the ISA controller.
+ @retval Other The ISA controller could not be placed in the requested state.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_ENABLE_DEVICE)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ IN EFI_ISA_ACPI_DEVICE_ID *Device,
+ IN BOOLEAN Enable
+ );
+
+/**
+ Initializes an ISA controller, so that it can be used. This service must be called
+ before SetResource(), EnableDevice(), or SetPower() will behave as expected.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
+
+ @retval EFI_SUCCESS Successfully initialized an ISA controller.
+ @retval Other The ISA controller could not be initialized.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_INIT_DEVICE)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ IN EFI_ISA_ACPI_DEVICE_ID *Device
+ );
+
+/**
+ Initializes all the HW states required for the ISA controllers on the ISA bus
+ to be enumerated and managed by the rest of the services in this prorotol.
+ This service must be called before any of the other services in this
+ protocol will function as expected.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+
+ @retval EFI_SUCCESS Successfully initialized all required hardware states.
+ @retval Other The ISA interface could not be initialized.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_INTERFACE_INIT)(
+ IN EFI_ISA_ACPI_PROTOCOL *This
+ );
+
+///
+/// The EFI_ISA_ACPI_PROTOCOL provides the services to enumerate and manage
+/// ISA controllers on an ISA bus. These services include the ability to initialize,
+/// enable, disable, and manage the power state of ISA controllers. It also
+/// includes services to query current resources, query possible resources,
+/// and assign resources to an ISA controller.
+///
+struct _EFI_ISA_ACPI_PROTOCOL {
+ EFI_ISA_ACPI_DEVICE_ENUMERATE DeviceEnumerate;
+ EFI_ISA_ACPI_SET_DEVICE_POWER SetPower;
+ EFI_ISA_ACPI_GET_CUR_RESOURCE GetCurResource;
+ EFI_ISA_ACPI_GET_POS_RESOURCE GetPosResource;
+ EFI_ISA_ACPI_SET_RESOURCE SetResource;
+ EFI_ISA_ACPI_ENABLE_DEVICE EnableDevice;
+ EFI_ISA_ACPI_INIT_DEVICE InitDevice;
+ EFI_ISA_ACPI_INTERFACE_INIT InterfaceInit;
+};
+
+extern EFI_GUID gEfiIsaAcpiProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
new file mode 100644
index 0000000000..30000305fb
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
@@ -0,0 +1,356 @@
+/** @file
+ ISA I/O Protocol is used by ISA device drivers to perform I/O, MMIO and DMA
+ operations on the ISA controllers they manage.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_ISA_IO_H_
+#define _EFI_ISA_IO_H_
+
+#include <Protocol/IsaAcpi.h>
+
+///
+/// Global ID for the EFI_ISA_IO_PROTOCOL
+///
+#define EFI_ISA_IO_PROTOCOL_GUID \
+ { \
+ 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+///
+/// Forward declaration for the EFI_ISA_IO_PROTOCOL.
+///
+typedef struct _EFI_ISA_IO_PROTOCOL EFI_ISA_IO_PROTOCOL;
+
+///
+/// Width of EFI_ISA_IO_PROTOCOL I/O Port and MMIO operations.
+///
+typedef enum {
+ EfiIsaIoWidthUint8 = 0, ///< 8-bit operation.
+ EfiIsaIoWidthUint16, ///< 16-bit operation.
+ EfiIsaIoWidthUint32, ///< 32-bit operation
+ EfiIsaIoWidthReserved,
+ EfiIsaIoWidthFifoUint8, ///< 8-bit FIFO operation.
+ EfiIsaIoWidthFifoUint16, ///< 16-bit FIFO operation.
+ EfiIsaIoWidthFifoUint32, ///< 32-bit FIFO operation.
+ EfiIsaIoWidthFifoReserved,
+ EfiIsaIoWidthFillUint8, ///< 8-bit Fill operation.
+ EfiIsaIoWidthFillUint16, ///< 16-bit Fill operation.
+ EfiIsaIoWidthFillUint32, ///< 32-bit Fill operation.
+ EfiIsaIoWidthFillReserved,
+ EfiIsaIoWidthMaximum
+} EFI_ISA_IO_PROTOCOL_WIDTH;
+
+///
+/// Attributes for the EFI_ISA_IO_PROTOCOL common DMA buffer allocations.
+///
+#define EFI_ISA_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x080 ///< Map a memory range so write are combined.
+#define EFI_ISA_IO_ATTRIBUTE_MEMORY_CACHED 0x800 ///< Map a memory range so all read and write accesses are cached.
+#define EFI_ISA_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000 ///< Disable a memory range.
+
+///
+/// Channel attribute for EFI_ISA_IO_PROTOCOL slave DMA requests
+///
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE 0x001 ///< Set the speed of the DMA transfer in compatible mode.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_A 0x002 ///< Not supported.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_B 0x004 ///< Not supported.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_C 0x008 ///< Not supported.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8 0x010 ///< Request 8-bit DMA transfers. Only available on channels 0..3.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16 0x020 ///< Request 16-bit DMA transfers. Only available on channels 4..7.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE 0x040 ///< Request a single DMA transfer.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE 0x080 ///< Request multiple DMA transfers until TC (Terminal Count) or EOP (End of Process).
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_AUTO_INITIALIZE 0x100 ///< Automatically reload base and count at the end of the DMA transfer.
+
+///
+/// The DMA opreration type for EFI_ISA_IO_PROTOCOL DMA requests.
+///
+typedef enum {
+ ///
+ /// A read operation from system memory by a bus master.
+ ///
+ EfiIsaIoOperationBusMasterRead,
+ ///
+ /// A write operation to system memory by a bus master.
+ ///
+ EfiIsaIoOperationBusMasterWrite,
+ ///
+ /// Provides both read and write access to system memory by both the processor
+ /// and a bus master. The buffer is coherent from both the processor's and the
+ /// bus master's point of view.
+ ///
+ EfiIsaIoOperationBusMasterCommonBuffer,
+ ///
+ /// A read operation from system memory by a slave device.
+ ///
+ EfiIsaIoOperationSlaveRead,
+ ///
+ /// A write operation to system memory by a slave master.
+ ///
+ EfiIsaIoOperationSlaveWrite,
+ EfiIsaIoOperationMaximum
+} EFI_ISA_IO_PROTOCOL_OPERATION;
+
+/**
+ Performs ISA I/O and MMIO Read/Write Cycles
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ @param[in] Width Specifies the width of the I/O or MMIO operation.
+ @param[in] Offset The offset into the ISA I/O or MMIO space to start the
+ operation.
+ @param[in] Count The number of I/O or MMIO operations to perform.
+ @param[in, out] Buffer For read operations, the destination buffer to store
+ the results. For write operations, the source buffer to
+ write data from.
+
+ @retval EFI_SUCCESS The data was successfully read from or written to the device.
+ @retval EFI_UNSUPPORTED The Offset is not valid for this device.
+ @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_IO_MEM)(
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+///
+/// Structure of functions for accessing ISA I/O and MMIO space.
+///
+typedef struct {
+ ///
+ /// Read from ISA I/O or MMIO space.
+ ///
+ EFI_ISA_IO_PROTOCOL_IO_MEM Read;
+ ///
+ /// Write to ISA I/O or MMIO space.
+ ///
+ EFI_ISA_IO_PROTOCOL_IO_MEM Write;
+} EFI_ISA_IO_PROTOCOL_ACCESS;
+
+/**
+ Copies data from one region of ISA MMIO space to another region of ISA
+ MMIO space.
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ @param[in] Width Specifies the width of the MMIO copy operation.
+ @param[in] DestOffset The offset of the destination in ISA MMIO space.
+ @param[in] SrcOffset The offset of the source in ISA MMIO space.
+ @param[in] Count The number tranfers to perform for this copy operation.
+
+ @retval EFI_SUCCESS The data was copied sucessfully.
+ @retval EFI_UNSUPPORTED The DestOffset or SrcOffset is not valid for this device.
+ @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_COPY_MEM)(
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 DestOffset,
+ IN UINT32 SrcOffset,
+ IN UINTN Count
+ );
+
+/**
+ Maps a memory region for DMA.
+
+ This function returns the device-specific addresses required to access system memory.
+ This function is used to map system memory for ISA DMA operations. All ISA DMA
+ operations must be performed through their mapped addresses, and such mappings must
+ be freed with EFI_ISA_IO_PROTOCOL.Unmap() after the DMA operation is completed.
+
+ If the DMA operation is a single read or write data transfer through an ISA bus
+ master, then EfiIsaIoOperationBusMasterRead or EfiIsaIoOperationBusMasterWrite
+ is used and the range is unmapped to complete the operation. If the DMA operation
+ is a single read or write data transfer through an ISA slave controller, then
+ EfiIsaIoOperationSlaveRead or EfiIsaIoOperationSlaveWrite is used and the range
+ is unmapped to complete the operation.
+
+ If performing a DMA read operation, all the data must be present in system memory before the Map() is performed. Similarly,
+ if performing a DMA write operation, the data must not be accessed in system
+ memory until EFI_ISA_IO_PROTOCOL.Unmap() is performed. Bus master operations that
+ require both read and write access or require multiple host device interactions
+ within the same mapped region must use EfiIsaIoOperationBusMasterCommonBuffer.
+ However, only memory allocated via the EFI_ISA_IO_PROTOCOL.AllocateBuffer() interface
+ is guaranteed to be able to be mapped for this operation type. In all mapping
+ requests the NumberOfBytes returned may be less than originally requested. It is
+ the caller's responsibility to make additional requests to complete the entire
+ transfer.
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ @param[in] Operation Indicates the type of DMA (slave or bus master),
+ and if the DMA operation is going to read or
+ write to system memory.
+ @param[in] ChannelNumber The slave channel number to use for this DMA
+ operation. If Operation and ChannelAttributes
+ shows that this device performs bus mastering
+ DMA, then this field is ignored. The legal
+ range for this field is 0..7.
+ @param[in] ChannelAttributes A bitmask of the attributes used to configure
+ the slave DMA channel for this DMA operation.
+ See EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_* for the
+ legal bit combinations.
+ @param[in] HostAddress The system memory address to map to the device.
+ @param[in, out] NumberOfBytes On input the number of bytes to map. On
+ output the number of bytes that were mapped.
+ @param[out] DeviceAddress The resulting map address for the bus master
+ device to use to access the hosts HostAddress.
+ @param[out] Mapping A returned value that must be passed to into
+ EFI_ISA_IO_PROTOCOL.Unmap() to free all the the
+ resources associated with this map request.
+
+ @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
+ @retval EFI_INVALID_PARAMETER The Operation is undefined.
+ @retval EFI_INVALID_PARAMETER The HostAddress is undefined.
+ @retval EFI_UNSUPPORTED The HostAddress can not be mapped as a common buffer.
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_MAP)(
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_OPERATION Operation,
+ IN UINT8 ChannelNumber OPTIONAL,
+ IN UINT32 ChannelAttributes,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ );
+
+/**
+ Unmaps a memory region that was previously mapped with EFI_ISA_IO_PROTOCOL.Map().
+
+ The EFI_ISA_IO_PROTOCOL.Map() operation is completed and any corresponding
+ resources are released. If the operation was EfiIsaIoOperationSlaveWrite
+ or EfiIsaIoOperationBusMasterWrite, the data is committed to system memory.
+ Any resources used for the mapping are freed.
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ @param[in] Mapping The mapping value returned from EFI_ISA_IO_PROTOCOL.Map().
+
+ @retval EFI_SUCCESS The memory region was unmapped.
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_UNMAP)(
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ );
+
+/**
+ Allocates pages that are suitable for an EfiIsaIoOperationBusMasterCommonBuffer
+ mapping.
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ @param[in] Type The type allocation to perform.
+ @param[in] MemoryType The type of memory to allocate.
+ @param[in] Pages The number of pages to allocate.
+ @param[out] HostAddress A pointer to store the base address of the allocated range.
+ @param[in] Attributes The requested bit mask of attributes for the allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were allocated.
+ @retval EFI_INVALID_PARAMETER Type is invalid.
+ @retval EFI_INVALID_PARAMETER MemoryType is invalid.
+ @retval EFI_INVALID_PARAMETER HostAddress is NULL.
+ @retval EFI_UNSUPPORTED Attributes is unsupported.
+ @retval EFI_UNSUPPORTED The memory range specified by HostAddress, Pages,
+ and Type is not available for common buffer use.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER)(
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ );
+
+/**
+ Frees a common buffer that was allocated with EFI_ISA_IO_PROTOCOL.AllocateBuffer().
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ @param[in] Pages The number of pages to free from the previously allocated common buffer.
+ @param[in] HostAddress The base address of the previously allocated common buffer.
+
+
+ @retval EFI_SUCCESS The requested memory pages were freed.
+ @retval EFI_INVALID_PARAMETER The memory was not allocated with EFI_ISA_IO.AllocateBufer().
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_FREE_BUFFER)(
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ );
+
+/**
+ Flushes a DMA buffer, which forces all DMA posted write transactions to complete.
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The DMA buffers were flushed.
+ @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_FLUSH)(
+ IN EFI_ISA_IO_PROTOCOL *This
+ );
+
+///
+/// The EFI_ISA_IO_PROTOCOL provides the basic Memory, I/O, and DMA interfaces
+/// used to abstract accesses to ISA controllers. There is one EFI_ISA_IO_PROTOCOL
+/// instance for each ISA controller on a ISA bus. A device driver that wishes
+/// to manage an ISA controller in a system will have to retrieve the
+/// ISA_PCI_IO_PROTOCOL instance associated with the ISA controller.
+///
+struct _EFI_ISA_IO_PROTOCOL {
+ EFI_ISA_IO_PROTOCOL_ACCESS Mem;
+ EFI_ISA_IO_PROTOCOL_ACCESS Io;
+ EFI_ISA_IO_PROTOCOL_COPY_MEM CopyMem;
+ EFI_ISA_IO_PROTOCOL_MAP Map;
+ EFI_ISA_IO_PROTOCOL_UNMAP Unmap;
+ EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer;
+ EFI_ISA_IO_PROTOCOL_FREE_BUFFER FreeBuffer;
+ EFI_ISA_IO_PROTOCOL_FLUSH Flush;
+ ///
+ /// The list of I/O , MMIO, DMA, and Interrupt resources associated with the
+ /// ISA controller abstracted by this instance of the EFI_ISA_IO_PROTOCOL.
+ ///
+ EFI_ISA_ACPI_RESOURCE_LIST *ResourceList;
+ ///
+ /// The size, in bytes, of the ROM image.
+ ///
+ UINT32 RomSize;
+ ///
+ /// A pointer to the in memory copy of the ROM image. The ISA Bus Driver is responsible
+ /// for allocating memory for the ROM image, and copying the contents of the ROM to memory
+ /// during ISA Bus initialization.
+ ///
+ VOID *RomImage;
+};
+
+extern EFI_GUID gEfiIsaIoProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
new file mode 100644
index 0000000000..c38f2feba7
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
@@ -0,0 +1,291 @@
+/** @file
+ This protocol abstracts the 8259 interrupt controller. This includes
+ PCI IRQ routing needed to program the PCI Interrupt Line register.
+
+ Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ This protocol is defined in Framework for EFI Compatibility Support Module spec
+ Version 0.97.
+
+**/
+
+#ifndef _EFI_LEGACY_8259_H_
+#define _EFI_LEGACY_8259_H_
+
+
+#define EFI_LEGACY_8259_PROTOCOL_GUID \
+ { \
+ 0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1 } \
+ }
+
+typedef struct _EFI_LEGACY_8259_PROTOCOL EFI_LEGACY_8259_PROTOCOL;
+
+typedef enum {
+ Efi8259Irq0,
+ Efi8259Irq1,
+ Efi8259Irq2,
+ Efi8259Irq3,
+ Efi8259Irq4,
+ Efi8259Irq5,
+ Efi8259Irq6,
+ Efi8259Irq7,
+ Efi8259Irq8,
+ Efi8259Irq9,
+ Efi8259Irq10,
+ Efi8259Irq11,
+ Efi8259Irq12,
+ Efi8259Irq13,
+ Efi8259Irq14,
+ Efi8259Irq15,
+ Efi8259IrqMax
+} EFI_8259_IRQ;
+
+typedef enum {
+ Efi8259LegacyMode,
+ Efi8259ProtectedMode,
+ Efi8259MaxMode
+} EFI_8259_MODE;
+
+/**
+ Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
+ the legacy mode mask and the protected mode mask. The base address for the 8259
+ is different for legacy and protected mode, so two masks are required.
+
+ @param This The protocol instance pointer.
+ @param MasterBase The base vector for the Master PIC in the 8259 controller.
+ @param SlaveBase The base vector for the Slave PIC in the 8259 controller.
+
+ @retval EFI_SUCCESS The new bases were programmed.
+ @retval EFI_DEVICE_ERROR A device error occured programming the vector bases.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_SET_VECTOR_BASE)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT8 MasterBase,
+ IN UINT8 SlaveBase
+ );
+
+/**
+ Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
+ the legacy mode mask and the protected mode mask. The base address for the 8259
+ is different for legacy and protected mode, so two masks are required.
+
+ @param This The protocol instance pointer.
+ @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15.
+ @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
+ @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15.
+ @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
+
+ @retval EFI_SUCCESS 8259 status returned.
+ @retval EFI_DEVICE_ERROR Error reading 8259.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_GET_MASK)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ OUT UINT16 *LegacyMask, OPTIONAL
+ OUT UINT16 *LegacyEdgeLevel, OPTIONAL
+ OUT UINT16 *ProtectedMask, OPTIONAL
+ OUT UINT16 *ProtectedEdgeLevel OPTIONAL
+ );
+
+/**
+ Set the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
+ the legacy mode mask and the protected mode mask. The base address for the 8259
+ is different for legacy and protected mode, so two masks are required.
+ Also set the edge/level masks.
+
+ @param This The protocol instance pointer.
+ @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15.
+ @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
+ @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15.
+ @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
+
+ @retval EFI_SUCCESS 8259 status returned.
+ @retval EFI_DEVICE_ERROR Error writing 8259.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_SET_MASK)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT16 *LegacyMask, OPTIONAL
+ IN UINT16 *LegacyEdgeLevel, OPTIONAL
+ IN UINT16 *ProtectedMask, OPTIONAL
+ IN UINT16 *ProtectedEdgeLevel OPTIONAL
+ );
+
+/**
+ Set the 8259 mode of operation. The base address for the 8259 is different for
+ legacy and protected mode. The legacy mode requires the master 8259 to have a
+ master base of 0x08 and the slave base of 0x70. The protected mode base locations
+ are not defined. Interrupts must be masked by the caller before this function
+ is called. The interrupt mask from the current mode is saved. The interrupt
+ mask for the new mode is Mask, or if Mask does not exist the previously saved
+ mask is used.
+
+ @param This The protocol instance pointer.
+ @param Mode The mode of operation. i.e. the real mode or protected mode.
+ @param Mask Optional interupt mask for the new mode.
+ @param EdgeLevel Optional trigger mask for the new mode.
+
+ @retval EFI_SUCCESS 8259 programmed.
+ @retval EFI_DEVICE_ERROR Error writing to 8259.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_SET_MODE)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_MODE Mode,
+ IN UINT16 *Mask, OPTIONAL
+ IN UINT16 *EdgeLevel OPTIONAL
+ );
+
+/**
+ Convert from IRQ to processor interrupt vector number.
+
+ @param This The protocol instance pointer.
+ @param Irq 8259 IRQ0 - IRQ15.
+ @param Vector The processor vector number that matches an Irq.
+
+ @retval EFI_SUCCESS The Vector matching Irq is returned.
+ @retval EFI_INVALID_PARAMETER The Irq not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_GET_VECTOR)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ OUT UINT8 *Vector
+ );
+
+/**
+ Enable Irq by unmasking interrupt in 8259
+
+ @param This The protocol instance pointer.
+ @param Irq 8259 IRQ0 - IRQ15.
+ @param LevelTriggered TRUE if level triggered. FALSE if edge triggered.
+
+ @retval EFI_SUCCESS The Irq was enabled on 8259.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_ENABLE_IRQ)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ IN BOOLEAN LevelTriggered
+ );
+
+/**
+ Disable Irq by masking interrupt in 8259
+
+ @param This The protocol instance pointer.
+ @param Irq 8259 IRQ0 - IRQ15.
+
+ @retval EFI_SUCCESS The Irq was disabled on 8259.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_DISABLE_IRQ)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ );
+
+/**
+ PciHandle represents a PCI config space of a PCI function. Vector
+ represents Interrupt Pin (from PCI config space) and it is the data
+ that is programmed into the Interrupt Line (from the PCI config space)
+ register.
+
+ @param This The protocol instance pointer.
+ @param PciHandle The PCI function to return the vector for.
+ @param Vector The vector for the function it matches.
+
+ @retval EFI_SUCCESS A valid Vector was returned.
+ @retval EFI_INVALID_PARAMETER PciHandle not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_GET_INTERRUPT_LINE)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT UINT8 *Vector
+ );
+
+/**
+ Send an EOI to 8259
+
+ @param This The protocol instance pointer.
+ @param Irq 8259 IRQ0 - IRQ15.
+
+ @retval EFI_SUCCESS EOI was successfully sent to 8259.
+ @retval EFI_INVALID_PARAMETER The Irq isnot valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_END_OF_INTERRUPT)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ );
+
+/**
+ @par Protocol Description:
+ Abstracts the 8259 and APIC hardware control between EFI usage and
+ Compatibility16 usage.
+
+ @param SetVectorBase
+ Sets the vector bases for master and slave PICs.
+
+ @param GetMask
+ Gets IRQ and edge/level masks for 16-bit real mode and 32-bit protected mode.
+
+ @param SetMask
+ Sets the IRQ and edge\level masks for 16-bit real mode and 32-bit protected mode.
+
+ @param SetMode
+ Sets PIC mode to 16-bit real mode or 32-bit protected mode.
+
+ @param GetVector
+ Gets the base vector assigned to an IRQ.
+
+ @param EnableIrq
+ Enables an IRQ.
+
+ @param DisableIrq
+ Disables an IRQ.
+
+ @param GetInterruptLine
+ Gets an IRQ that is assigned to a PCI device.
+
+ @param EndOfInterrupt
+ Issues the end of interrupt command.
+
+**/
+struct _EFI_LEGACY_8259_PROTOCOL {
+ EFI_LEGACY_8259_SET_VECTOR_BASE SetVectorBase;
+ EFI_LEGACY_8259_GET_MASK GetMask;
+ EFI_LEGACY_8259_SET_MASK SetMask;
+ EFI_LEGACY_8259_SET_MODE SetMode;
+ EFI_LEGACY_8259_GET_VECTOR GetVector;
+ EFI_LEGACY_8259_ENABLE_IRQ EnableIrq;
+ EFI_LEGACY_8259_DISABLE_IRQ DisableIrq;
+ EFI_LEGACY_8259_GET_INTERRUPT_LINE GetInterruptLine;
+ EFI_LEGACY_8259_END_OF_INTERRUPT EndOfInterrupt;
+};
+
+extern EFI_GUID gEfiLegacy8259ProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h
new file mode 100644
index 0000000000..640ac4943d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/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/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
new file mode 100644
index 0000000000..c79111d811
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
@@ -0,0 +1,54 @@
+/** @file
+ OVMF Platform definitions
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __OVMF_PLATFORMS_H__
+#define __OVMF_PLATFORMS_H__
+
+#include <Library/PciLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <IndustryStandard/X58Ich10.h>
+#include <IndustryStandard/I440FxPiix4.h> // TODO: remove
+
+//
+// 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/LoadLinuxLib/Ia32/JumpToKernel.nasm b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm
new file mode 100644
index 0000000000..3f3cd33c8a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm
@@ -0,0 +1,41 @@
+; @file
+; Copyright (c) 2006 - 2013 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..c4cc4dd8e7
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
@@ -0,0 +1,52 @@
+/** @file
+ Boot UEFI Linux.
+
+ Copyright (c) 2008 - 2013 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/LoadLinuxLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
new file mode 100644
index 0000000000..89664f4e42
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
@@ -0,0 +1,42 @@
+## @file
+#
+# Copyright (c) 2008 - 2012 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LoadLinuxLib
+ FILE_GUID = 63CC8497-C9D0-46A8-AC08-49DF92A2FF62
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LoadLinuxLib
+
+#
+# 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
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ MemoryAllocationLib
+ BaseMemoryLib
+
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..79e6b8e7ba
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm
@@ -0,0 +1,85 @@
+; @file
+; Copyright (c) 2006 - 2013 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..92aa038cdd
--- /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 - 2011 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..e4c3b7ccff
--- /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 - 2018 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/SerializeVariablesLib/SerializeVariablesLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h
new file mode 100644
index 0000000000..7e78cd4b21
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h
@@ -0,0 +1,33 @@
+/** @file
+ Serialize Variables Library implementation
+
+ Copyright (c) 2009 - 2011 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..25901192b2
--- /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 - 2018 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
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
new file mode 100644
index 0000000000..63b5e52575
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
@@ -0,0 +1,37 @@
+/** @file
+ This driver effectuates OVMF's 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/PlatformDxe/Platform.inf b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
new file mode 100644
index 0000000000..804ab59610
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.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 = PlatformDxe
+ 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/SimicsOpenBoardPkg.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
+ gSimicsX58PlatformConfigGuid
+
+[Depex]
+ gEfiHiiConfigRoutingProtocolGuid AND
+ gEfiHiiDatabaseProtocolGuid AND
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid
diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
new file mode 100644
index 0000000000..6d68cbeb4f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/PlatformDxe/PlatformConfig.h b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
new file mode 100644
index 0000000000..d3f041ddea
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/PlatformDxe/PlatformForms.vfr b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
new file mode 100644
index 0000000000..1c02565ebb
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/SimicsX58PlatformConfig.h>
+#include "Platform.h"
+
+formset
+ guid = SIMICSX58_PLATFORM_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 = SIMICSX58_PLATFORM_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/PlatformPei/Cmos.h b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
new file mode 100644
index 0000000000..616d2d74cb
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
@@ -0,0 +1,50 @@
+/** @file
+ PC/AT CMOS access routines
+
+ Copyright (c) 2006 - 2009 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/PlatformPei/Platform.h b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
new file mode 100644
index 0000000000..5b1a9b5f57
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
@@ -0,0 +1,93 @@
+/** @file
+ Platform PEI module include file.
+
+ Copyright (c) 2006 - 2016 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
+ );
+
+EFI_STATUS
+PeiFvInitialization (
+ 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/PlatformPei/PlatformPei.inf b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
new file mode 100644
index 0000000000..eb8048c655
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
@@ -0,0 +1,109 @@
+## @file
+# Platform PEI driver
+#
+# This module provides platform specific function to detect boot mode.
+# Copyright (c) 2006 - 2018 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformPei
+ 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
+ Fv.c
+ MemDetect.c
+ Platform.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[Guids]
+ gEfiMemoryTypeInformationGuid
+ gEfiSmmPeiSmramMemoryReserveGuid ## CONSUMES
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ HobLib
+ IoLib
+ PciLib
+ PeiResourcePublicationLib
+ PeiServicesLib
+ PeiServicesTablePointerLib
+ PeimEntryPoint
+ MtrrLib
+ PcdLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
+ gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+ gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+ 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/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
new file mode 100644
index 0000000000..b9bcb5d2bd
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
@@ -0,0 +1,38 @@
+## @file
+#
+# Copyright (c) 2018 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..da165ac947
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
@@ -0,0 +1,35 @@
+## @file
+#
+# Copyright (c) 2018 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/SimicsOpenBoardPkg.dec b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
new file mode 100644
index 0000000000..17c87aca8c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
@@ -0,0 +1,168 @@
+## @file
+# EFI/Framework Simics X58 platform
+#
+# Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = SimicsX58Pkg
+ PACKAGE_GUID = E6A03E0D-5944-4dc6-9292-090D609EDD3A
+ PACKAGE_VERSION = 0.1
+
+[Includes]
+ Include
+
+[Guids]
+ gSimicsX58PkgTokenSpaceGuid = {0x5b276d20, 0x37d0, 0x4af0, {0x8d, 0x04, 0x47, 0x91, 0x2b, 0x7c, 0x1d, 0x44}}
+ gSimicsX58PlatformConfigGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
+
+[Protocols]
+ gEfiLegacy8259ProtocolGuid = {0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1}}
+ gEfiIsaAcpiProtocolGuid = {0x64a892dc, 0x5561, 0x4536, {0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55}}
+ gEfiIsaIoProtocolGuid = {0x7ee2bd44, 0x3da0, 0x11d4, {0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
+
+[PcdsFixedAtBuild]
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase|0x0|UINT32|0
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize|0x0|UINT32|1
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase|0x0|UINT32|0x15
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize|0x0|UINT32|0x16
+
+ #TODO: Remove these two when we integrate new PlatformPei
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvBase|0x00800000|UINT32|2
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvSize|0x00500000|UINT32|3
+
+ ## 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
+
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase|0x0|UINT32|0x8
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize|0x0|UINT32|0x9
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareFdSize|0x0|UINT32|0xa
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareBlockSize|0|UINT32|0xb
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase|0x0|UINT32|0xc
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase|0x0|UINT32|0xd
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase|0x0|UINT32|0xe
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFdBaseAddress|0x0|UINT32|0xf
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase|0x0|UINT32|0x11
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesSize|0x0|UINT32|0x12
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|0x0|UINT32|0x13
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize|0x0|UINT32|0x14
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase|0x0|UINT32|0x18
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize|0x0|UINT32|0x19
+ gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT32|0x1a
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd|0x0|UINT32|0x1f
+
+[PcdsDynamic, PcdsDynamicEx]
+
+ # TODO: investigate whether next two Pcds are needed
+ gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|0x28
+ gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0|UINT16|0x1b
+
+ ## The IO port aperture shared by all PCI root bridges.
+ #
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x23
+
+ ## The 32-bit MMIO aperture shared by all PCI root bridges.
+ #
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT64|0x24
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT64|0x25
+
+ ## The 64-bit MMIO aperture shared by all PCI root bridges.
+ #
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x26
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x27
+
+[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
+
+
+[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
+ gSimicsX58PkgTokenSpaceGuid.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 | (gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures & 0xF8) == 0
+ gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0x00010040
\ No newline at end of file
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
new file mode 100644
index 0000000000..38a71a3527
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
@@ -0,0 +1,38 @@
+/** @file
+ This driver installs SMBIOS information for OVMF
+
+ 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..6adaf0beb7
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
@@ -0,0 +1,51 @@
+## @file
+# This driver installs SMBIOS information for OVMF
+#
+# 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/SimicsOpenBoardPkg.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] 37+ messages in thread
* [edk2-platform patch 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio
2019-08-09 22:46 [edk2-platform patch 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
` (2 preceding siblings ...)
2019-08-09 22:46 ` [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules David Wei
@ 2019-08-09 22:46 ` David Wei
2019-08-15 19:01 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform David Wei
` (2 subsequent siblings)
6 siblings, 2 replies; 37+ messages in thread
From: David Wei @ 2019-08-09 22:46 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>
Contributed-under: TianoCore Contribution Agreement 1.0
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..93e8cefe6c
--- /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 - 2016 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..6fa8c53833
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c
@@ -0,0 +1,272 @@
+/** @file
+ Super I/O specific implementation.
+
+ Copyright (c) 2010 - 2016 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..0e308a5f18
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c
@@ -0,0 +1,600 @@
+/** @file
+ EFI Driver following Driver Binding Protocol.
+
+ Copyright (c) 2010 - 2016 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..005d603bdd
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c
@@ -0,0 +1,249 @@
+/** @file
+ Super I/O Interface implementation.
+
+ Copyright (c) 2010 - 2016 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..36a9069f0f
--- /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 - 2016 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..a1f558117e
--- /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 - 2016 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..542b032abb
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h
@@ -0,0 +1,15 @@
+/** @file
+ Super I/O register definitions
+
+ Copyright (c) 2010 - 2016 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..fea2e9c4c5
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h
@@ -0,0 +1,195 @@
+/** @file
+ Super I/O specific header.
+
+ Copyright (c) 2010 - 2016 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..7386cb2e19
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h
@@ -0,0 +1,134 @@
+/** @file
+ Header file for Driver Binding Protocol.
+
+ Copyright (c) 2010 - 2016 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..6f95090b17
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h
@@ -0,0 +1,143 @@
+/** @file
+ Super I/O Interface function declarations.
+
+ Copyright (c) 2010 - 2016 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] 37+ messages in thread
* [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
2019-08-09 22:46 [edk2-platform patch 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
` (3 preceding siblings ...)
2019-08-09 22:46 ` [edk2-platform patch 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio David Wei
@ 2019-08-09 22:46 ` David Wei
2019-08-15 19:38 ` Nate DeSimone
` (2 more replies)
2019-08-09 22:46 ` [edk2-platform patch 6/7] SimicsOpenBoardPkg: Add board module for QSP Build tip David Wei
2019-08-09 22:46 ` [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform David Wei
6 siblings, 3 replies; 37+ messages in thread
From: David Wei @ 2019-08-09 22:46 UTC (permalink / raw)
To: devel
Cc: Hao Wu, Liming Gao, Ankit Sinha, Agyeman Prince,
Kubacki Michael A, Nate DeSimone, Michael D Kinney
Overrides/MdeModulePkg/Library/PciHostBridgeLib - it is platform related. should be Customized
Overrides/MdeModulePkg/Logo - the Logo image is Customized
Overrides/MdePkg/Library/BasePciLibCf8 - use the functions specific for SIMICS
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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++
.../Library/PlatformBootManagerLib/BdsPlatform.c | 1553 +++++++++++++++++++
.../Library/PlatformBootManagerLib/PlatformData.c | 35 +
.../Overrides/MdeModulePkg/Logo/Logo.c | 154 ++
.../MdePkg/Library/BasePciLibCf8/PciLib.c | 1221 +++++++++++++++
.../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 | 417 ++++++
.../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++
.../8259InterruptControllerDxe/8259.c | 622 ++++++++
.../Library/PciHostBridgeLib/PciHostBridge.h | 68 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 50 +
.../Library/PlatformBootManagerLib/BdsPlatform.h | 156 ++
.../PlatformBootManagerLib.inf | 69 +
.../Overrides/MdeModulePkg/Logo/Logo.bmp | Bin 0 -> 141078 bytes
.../Overrides/MdeModulePkg/Logo/Logo.idf | 10 +
.../Overrides/MdeModulePkg/Logo/Logo.inf | 28 +
.../Overrides/MdeModulePkg/Logo/Logo.uni | 16 +
.../Overrides/MdeModulePkg/Logo/LogoDxe.inf | 55 +
.../Overrides/MdeModulePkg/Logo/LogoDxe.uni | 16 +
| 14 +
| 14 +
.../Library/BasePciLibCf8/DxePciLibX58Ich10.inf | 40 +
.../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 +
.../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++
.../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++
.../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 73 +
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 281 ++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 +
.../8259InterruptControllerDxe/8259.h | 218 +++
.../8259InterruptControllerDxe/8259.inf | 46 +
.../8259InterruptControllerDxe/Legacy8259.uni | 16 +
| 14 +
41 files changed, 11062 insertions(+)
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.bmp
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
new file mode 100644
index 0000000000..2aaa4b3e90
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -0,0 +1,419 @@
+/** @file
+ OVMF'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 <IndustryStandard/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/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c
new file mode 100644
index 0000000000..0b66862e46
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -0,0 +1,1553 @@
+/** @file
+ Platform BDS customizations.
+
+ Copyright (c) 2004 - 2018 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
+ //
+ BootLogoEnableLogo();
+
+ 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/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c
new file mode 100644
index 0000000000..5f1b16dd56
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/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 - 2017 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/Overrides/MdeModulePkg/Logo/Logo.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
new file mode 100644
index 0000000000..d4a75ad140
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
@@ -0,0 +1,154 @@
+/** @file
+ Logo DXE Driver, install Edkii Platform Logo protocol.
+
+ Copyright (c) 2016 - 2017 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/HiiImageEx.h>
+#include <Protocol/PlatformLogo.h>
+#include <Protocol/HiiPackageList.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+typedef struct {
+ EFI_IMAGE_ID ImageId;
+ EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE Attribute;
+ INTN OffsetX;
+ INTN OffsetY;
+} LOGO_ENTRY;
+
+EFI_HII_IMAGE_EX_PROTOCOL *mHiiImageEx;
+EFI_HII_HANDLE mHiiHandle;
+LOGO_ENTRY mLogos[] = {
+ {
+ IMAGE_TOKEN (IMG_LOGO),
+ EdkiiPlatformLogoDisplayAttributeCenter,
+ 0,
+ 0
+ }
+};
+
+/**
+ Load a platform logo image and return its data and attributes.
+
+ @param This The pointer to this protocol instance.
+ @param Instance The visible image instance is found.
+ @param Image Points to the image.
+ @param Attribute The display attributes of the image returned.
+ @param OffsetX The X offset of the image regarding the Attribute.
+ @param OffsetY The Y offset of the image regarding the Attribute.
+
+ @retval EFI_SUCCESS The image was fetched successfully.
+ @retval EFI_NOT_FOUND The specified image could not be found.
+**/
+EFI_STATUS
+EFIAPI
+GetImage (
+ IN EDKII_PLATFORM_LOGO_PROTOCOL *This,
+ IN OUT UINT32 *Instance,
+ OUT EFI_IMAGE_INPUT *Image,
+ OUT EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE *Attribute,
+ OUT INTN *OffsetX,
+ OUT INTN *OffsetY
+ )
+{
+ UINT32 Current;
+ if (Instance == NULL || Image == NULL ||
+ Attribute == NULL || OffsetX == NULL || OffsetY == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Current = *Instance;
+ if (Current >= ARRAY_SIZE (mLogos)) {
+ return EFI_NOT_FOUND;
+ }
+
+ (*Instance)++;
+ *Attribute = mLogos[Current].Attribute;
+ *OffsetX = mLogos[Current].OffsetX;
+ *OffsetY = mLogos[Current].OffsetY;
+ return mHiiImageEx->GetImageEx (mHiiImageEx, mHiiHandle, mLogos[Current].ImageId, Image);
+}
+
+EDKII_PLATFORM_LOGO_PROTOCOL mPlatformLogo = {
+ GetImage
+};
+
+/**
+ Entrypoint of this module.
+
+ This function is the entrypoint of this module. It installs the Edkii
+ Platform Logo protocol.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeLogo (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_PACKAGE_LIST_HEADER *PackageList;
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
+ EFI_HANDLE Handle;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHiiDatabaseProtocolGuid,
+ NULL,
+ (VOID **) &HiiDatabase
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (
+ &gEfiHiiImageExProtocolGuid,
+ NULL,
+ (VOID **) &mHiiImageEx
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Retrieve HII package list from ImageHandle
+ //
+ Status = gBS->OpenProtocol (
+ ImageHandle,
+ &gEfiHiiPackageListProtocolGuid,
+ (VOID **) &PackageList,
+ ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "HII Image Package with logo not found in PE/COFF resource section\n"));
+ return Status;
+ }
+
+ //
+ // Publish HII package list to HII Database.
+ //
+ Status = HiiDatabase->NewPackageList (
+ HiiDatabase,
+ PackageList,
+ NULL,
+ &mHiiHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEdkiiPlatformLogoProtocolGuid, &mPlatformLogo,
+ NULL
+ );
+ }
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c
new file mode 100644
index 0000000000..7544117a03
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c
@@ -0,0 +1,1221 @@
+/** @file
+ PCI Library functions that use
+ (a) I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles, layering
+ on top of one PCI CF8 Library instance; or
+ (b) PCI Library functions that use the 256 MB PCI Express MMIO window to
+ perform PCI Configuration cycles, layering on PCI Express Library.
+
+ The decision is made in the entry point function, based on the OVMF platform
+ type, and then adhered to during the lifetime of the client module.
+
+ Copyright (C) 2016, Red Hat, Inc.
+ Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <IndustryStandard/X58Ich10.h>
+
+#include <Library/PciLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/PciExpressLib.h>
+#include <Library/PcdLib.h>
+
+STATIC BOOLEAN mRunningOnIch10;
+
+RETURN_STATUS
+EFIAPI
+InitializeConfigAccessMethod (
+ VOID
+ )
+{
+ mRunningOnIch10 = (PcdGet16 (PcdSimicsX58HostBridgePciDevId) ==
+ INTEL_ICH10_DEVICE_ID);
+ return RETURN_SUCCESS;
+}
+
+/**
+ Registers a PCI device so PCI configuration registers may be accessed after
+ SetVirtualAddressMap().
+
+ Registers the PCI device specified by Address so all the PCI configuration registers
+ associated with that PCI device may be accessed after SetVirtualAddressMap() is called.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @retval RETURN_SUCCESS The PCI device was registered for runtime access.
+ @retval RETURN_UNSUPPORTED An attempt was made to call this function
+ after ExitBootServices().
+ @retval RETURN_UNSUPPORTED The resources required to access the PCI device
+ at runtime could not be mapped.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
+ complete the registration.
+
+**/
+RETURN_STATUS
+EFIAPI
+PciRegisterForRuntimeAccess (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRegisterForRuntimeAccess (Address) :
+ PciCf8RegisterForRuntimeAccess (Address);
+}
+
+/**
+ Reads an 8-bit PCI configuration register.
+
+ Reads and returns the 8-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @return The read value from the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciRead8 (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRead8 (Address) :
+ PciCf8Read8 (Address);
+}
+
+/**
+ Writes an 8-bit PCI configuration register.
+
+ Writes the 8-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param Value The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciWrite8 (
+ IN UINTN Address,
+ IN UINT8 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWrite8 (Address, Value) :
+ PciCf8Write8 (Address, Value);
+}
+
+/**
+ Performs a bitwise OR of an 8-bit PCI configuration register with
+ an 8-bit value.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciOr8 (
+ IN UINTN Address,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressOr8 (Address, OrData) :
+ PciCf8Or8 (Address, OrData);
+}
+
+/**
+ Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
+ value.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciAnd8 (
+ IN UINTN Address,
+ IN UINT8 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAnd8 (Address, AndData) :
+ PciCf8And8 (Address, AndData);
+}
+
+/**
+ Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
+ value, followed a bitwise OR with another 8-bit value.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciAndThenOr8 (
+ IN UINTN Address,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAndThenOr8 (Address, AndData, OrData) :
+ PciCf8AndThenOr8 (Address, AndData, OrData);
+}
+
+/**
+ Reads a bit field of a PCI configuration register.
+
+ Reads the bit field in an 8-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Address The PCI configuration register to read.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+
+ @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldRead8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldRead8 (Address, StartBit, EndBit) :
+ PciCf8BitFieldRead8 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes a bit field to a PCI configuration register.
+
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 8-bit register is returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param Value The new value of the bit field.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldWrite8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldWrite8 (Address, StartBit, EndBit, Value) :
+ PciCf8BitFieldWrite8 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
+ writes the result back to the bit field in the 8-bit port.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldOr8 (Address, StartBit, EndBit, OrData) :
+ PciCf8BitFieldOr8 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
+ AND, and writes the result back to the bit field in the 8-bit register.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldAnd8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAnd8 (Address, StartBit, EndBit, AndData) :
+ PciCf8BitFieldAnd8 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
+ bitwise OR, and writes the result back to the bit field in the
+ 8-bit port.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise OR between the read result and
+ the value specified by AndData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldAndThenOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData) :
+ PciCf8BitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads a 16-bit PCI configuration register.
+
+ Reads and returns the 16-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @return The read value from the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciRead16 (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRead16 (Address) :
+ PciCf8Read16 (Address);
+}
+
+/**
+ Writes a 16-bit PCI configuration register.
+
+ Writes the 16-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param Value The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciWrite16 (
+ IN UINTN Address,
+ IN UINT16 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWrite16 (Address, Value) :
+ PciCf8Write16 (Address, Value);
+}
+
+/**
+ Performs a bitwise OR of a 16-bit PCI configuration register with
+ a 16-bit value.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciOr16 (
+ IN UINTN Address,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressOr16 (Address, OrData) :
+ PciCf8Or16 (Address, OrData);
+}
+
+/**
+ Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
+ value.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciAnd16 (
+ IN UINTN Address,
+ IN UINT16 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAnd16 (Address, AndData) :
+ PciCf8And16 (Address, AndData);
+}
+
+/**
+ Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
+ value, followed a bitwise OR with another 16-bit value.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciAndThenOr16 (
+ IN UINTN Address,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAndThenOr16 (Address, AndData, OrData) :
+ PciCf8AndThenOr16 (Address, AndData, OrData);
+}
+
+/**
+ Reads a bit field of a PCI configuration register.
+
+ Reads the bit field in a 16-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Address The PCI configuration register to read.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+
+ @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldRead16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldRead16 (Address, StartBit, EndBit) :
+ PciCf8BitFieldRead16 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes a bit field to a PCI configuration register.
+
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 16-bit register is returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param Value The new value of the bit field.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldWrite16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldWrite16 (Address, StartBit, EndBit, Value) :
+ PciCf8BitFieldWrite16 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
+ writes the result back to the bit field in the 16-bit port.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldOr16 (Address, StartBit, EndBit, OrData) :
+ PciCf8BitFieldOr16 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
+ AND, and writes the result back to the bit field in the 16-bit register.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldAnd16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAnd16 (Address, StartBit, EndBit, AndData) :
+ PciCf8BitFieldAnd16 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
+ bitwise OR, and writes the result back to the bit field in the
+ 16-bit port.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise OR between the read result and
+ the value specified by AndData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldAndThenOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData) :
+ PciCf8BitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads a 32-bit PCI configuration register.
+
+ Reads and returns the 32-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @return The read value from the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciRead32 (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRead32 (Address) :
+ PciCf8Read32 (Address);
+}
+
+/**
+ Writes a 32-bit PCI configuration register.
+
+ Writes the 32-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param Value The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciWrite32 (
+ IN UINTN Address,
+ IN UINT32 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWrite32 (Address, Value) :
+ PciCf8Write32 (Address, Value);
+}
+
+/**
+ Performs a bitwise OR of a 32-bit PCI configuration register with
+ a 32-bit value.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciOr32 (
+ IN UINTN Address,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressOr32 (Address, OrData) :
+ PciCf8Or32 (Address, OrData);
+}
+
+/**
+ Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
+ value.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciAnd32 (
+ IN UINTN Address,
+ IN UINT32 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAnd32 (Address, AndData) :
+ PciCf8And32 (Address, AndData);
+}
+
+/**
+ Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
+ value, followed a bitwise OR with another 32-bit value.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciAndThenOr32 (
+ IN UINTN Address,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAndThenOr32 (Address, AndData, OrData) :
+ PciCf8AndThenOr32 (Address, AndData, OrData);
+}
+
+/**
+ Reads a bit field of a PCI configuration register.
+
+ Reads the bit field in a 32-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Address The PCI configuration register to read.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+
+ @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldRead32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldRead32 (Address, StartBit, EndBit) :
+ PciCf8BitFieldRead32 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes a bit field to a PCI configuration register.
+
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 32-bit register is returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param Value The new value of the bit field.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldWrite32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldWrite32 (Address, StartBit, EndBit, Value) :
+ PciCf8BitFieldWrite32 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
+ writes the result back to the bit field in the 32-bit port.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldOr32 (Address, StartBit, EndBit, OrData) :
+ PciCf8BitFieldOr32 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
+ AND, and writes the result back to the bit field in the 32-bit register.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldAnd32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAnd32 (Address, StartBit, EndBit, AndData) :
+ PciCf8BitFieldAnd32 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
+ bitwise OR, and writes the result back to the bit field in the
+ 32-bit port.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise OR between the read result and
+ the value specified by AndData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldAndThenOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData) :
+ PciCf8BitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads a range of PCI configuration registers into a caller supplied buffer.
+
+ Reads the range of PCI configuration registers specified by StartAddress and
+ Size into the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be read. Size is
+ returned. When possible 32-bit PCI configuration read cycles are used to read
+ from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
+ and 16-bit PCI configuration read cycles may be used at the beginning and the
+ end of the range.
+
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param StartAddress The starting address that encodes the PCI Bus, Device,
+ Function and Register.
+ @param Size The size in bytes of the transfer.
+ @param Buffer The pointer to a buffer receiving the data read.
+
+ @return Size
+
+**/
+UINTN
+EFIAPI
+PciReadBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ OUT VOID *Buffer
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressReadBuffer (StartAddress, Size, Buffer) :
+ PciCf8ReadBuffer (StartAddress, Size, Buffer);
+}
+
+/**
+ Copies the data in a caller supplied buffer to a specified range of PCI
+ configuration space.
+
+ Writes the range of PCI configuration registers specified by StartAddress and
+ Size from the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be written. Size is
+ returned. When possible 32-bit PCI configuration write cycles are used to
+ write from StartAdress to StartAddress + Size. Due to alignment restrictions,
+ 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
+ and the end of the range.
+
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param StartAddress The starting address that encodes the PCI Bus, Device,
+ Function and Register.
+ @param Size The size in bytes of the transfer.
+ @param Buffer The pointer to a buffer containing the data to write.
+
+ @return Size written to StartAddress.
+
+**/
+UINTN
+EFIAPI
+PciWriteBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWriteBuffer (StartAddress, Size, Buffer) :
+ PciCf8WriteBuffer (StartAddress, Size, Buffer);
+}
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..b1d7552792
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
@@ -0,0 +1,1579 @@
+/** @file
+ ACPI Platform Driver
+
+ Copyright (c) 2017 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..a16c13466a
--- /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) 2017 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..8aa10a4a5b
--- /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) 2017 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..aa386ba149
--- /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) 2017 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..12e2feacb4
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c
@@ -0,0 +1,46 @@
+/** @file
+ ACPI WSMT table
+
+ Copyright (c) 2017 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..dd9cc80e42
--- /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 - 2010, 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..c2d82e7324
--- /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 - 2010 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..19ff5209d2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c
@@ -0,0 +1,417 @@
+/** @file
+ Graphics Output Protocol functions for the QEMU video controller.
+
+ Copyright (c) 2007 - 2018 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..fbf40e9eaf
--- /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 - 2010 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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
new file mode 100644
index 0000000000..b57bacdda4
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
@@ -0,0 +1,622 @@
+/** @file
+ This contains the installation function for the driver.
+
+ Copyright (c) 2005 - 2018 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "8259.h"
+
+//
+// Global for the Legacy 8259 Protocol that is produced by this driver
+//
+EFI_LEGACY_8259_PROTOCOL mInterrupt8259 = {
+ Interrupt8259SetVectorBase,
+ Interrupt8259GetMask,
+ Interrupt8259SetMask,
+ Interrupt8259SetMode,
+ Interrupt8259GetVector,
+ Interrupt8259EnableIrq,
+ Interrupt8259DisableIrq,
+ Interrupt8259GetInterruptLine,
+ Interrupt8259EndOfInterrupt
+};
+
+//
+// Global for the handle that the Legacy 8259 Protocol is installed
+//
+EFI_HANDLE m8259Handle = NULL;
+
+UINT8 mMasterBase = 0xff;
+UINT8 mSlaveBase = 0xff;
+EFI_8259_MODE mMode = Efi8259ProtectedMode;
+UINT16 mProtectedModeMask = 0xffff;
+UINT16 mLegacyModeMask;
+UINT16 mProtectedModeEdgeLevel = 0x0000;
+UINT16 mLegacyModeEdgeLevel;
+
+//
+// Worker Functions
+//
+
+/**
+ Write to mask and edge/level triggered registers of master and slave 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));
+}
+
+/**
+ Read from mask and edge/level triggered registers of master and slave PICs.
+
+ @param[out] Mask low byte for master PIC mask register,
+ high byte for slave PIC mask register.
+ @param[out] EdgeLevel low byte for master PIC edge/level triggered register,
+ high byte for slave PIC edge/level triggered register.
+
+**/
+VOID
+Interrupt8259ReadMask (
+ OUT UINT16 *Mask,
+ OUT UINT16 *EdgeLevel
+ )
+{
+ UINT16 MasterValue;
+ UINT16 SlaveValue;
+
+ if (Mask != NULL) {
+ MasterValue = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
+ SlaveValue = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
+
+ *Mask = (UINT16) (MasterValue | (SlaveValue << 8));
+ }
+
+ if (EdgeLevel != NULL) {
+ MasterValue = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER);
+ SlaveValue = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE);
+
+ *EdgeLevel = (UINT16) (MasterValue | (SlaveValue << 8));
+ }
+}
+
+//
+// Legacy 8259 Protocol Interface Functions
+//
+
+/**
+ Sets the base address for the 8259 master and slave PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
+ @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing to the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetVectorBase (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT8 MasterBase,
+ IN UINT8 SlaveBase
+ )
+{
+ UINT8 Mask;
+ EFI_TPL OriginalTpl;
+
+ OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+ //
+ // Set vector base for slave PIC
+ //
+ if (SlaveBase != mSlaveBase) {
+ mSlaveBase = SlaveBase;
+
+ //
+ // Initialization sequence is needed for setting vector base.
+ //
+
+ //
+ // Preserve interrtup mask register before initialization sequence
+ // because it will be cleared during initialization
+ //
+ Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
+
+ //
+ // ICW1: cascade mode, ICW4 write required
+ //
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, 0x11);
+
+ //
+ // ICW2: new vector base (must be multiple of 8)
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, mSlaveBase);
+
+ //
+ // ICW3: slave indentification code must be 2
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x02);
+
+ //
+ // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x01);
+
+ //
+ // Restore interrupt mask register
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, Mask);
+ }
+
+ //
+ // Set vector base for master PIC
+ //
+ if (MasterBase != mMasterBase) {
+ mMasterBase = MasterBase;
+
+ //
+ // Initialization sequence is needed for setting vector base.
+ //
+
+ //
+ // Preserve interrtup mask register before initialization sequence
+ // because it will be cleared during initialization
+ //
+ Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
+
+ //
+ // ICW1: cascade mode, ICW4 write required
+ //
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, 0x11);
+
+ //
+ // ICW2: new vector base (must be multiple of 8)
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, mMasterBase);
+
+ //
+ // ICW3: slave PIC is cascaded on IRQ2
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x04);
+
+ //
+ // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x01);
+
+ //
+ // Restore interrupt mask register
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, Mask);
+ }
+
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI);
+
+ gBS->RestoreTPL (OriginalTpl);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ OUT UINT16 *LegacyMask, OPTIONAL
+ OUT UINT16 *LegacyEdgeLevel, OPTIONAL
+ OUT UINT16 *ProtectedMask, OPTIONAL
+ OUT UINT16 *ProtectedEdgeLevel OPTIONAL
+ )
+{
+ if (LegacyMask != NULL) {
+ *LegacyMask = mLegacyModeMask;
+ }
+
+ if (LegacyEdgeLevel != NULL) {
+ *LegacyEdgeLevel = mLegacyModeEdgeLevel;
+ }
+
+ if (ProtectedMask != NULL) {
+ *ProtectedMask = mProtectedModeMask;
+ }
+
+ if (ProtectedEdgeLevel != NULL) {
+ *ProtectedEdgeLevel = mProtectedModeEdgeLevel;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT16 *LegacyMask, OPTIONAL
+ IN UINT16 *LegacyEdgeLevel, OPTIONAL
+ IN UINT16 *ProtectedMask, OPTIONAL
+ IN UINT16 *ProtectedEdgeLevel OPTIONAL
+ )
+{
+ if (LegacyMask != NULL) {
+ mLegacyModeMask = *LegacyMask;
+ }
+
+ if (LegacyEdgeLevel != NULL) {
+ mLegacyModeEdgeLevel = *LegacyEdgeLevel;
+ }
+
+ if (ProtectedMask != NULL) {
+ mProtectedModeMask = *ProtectedMask;
+ }
+
+ if (ProtectedEdgeLevel != NULL) {
+ mProtectedModeEdgeLevel = *ProtectedEdgeLevel;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Sets the mode of the PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Mode 16-bit real or 32-bit protected mode.
+ @param[in] Mask The value with which to set the interrupt mask.
+ @param[in] EdgeLevel The value with which to set the edge/level mask.
+
+ @retval EFI_SUCCESS The mode was set successfully.
+ @retval EFI_INVALID_PARAMETER The mode was not set.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMode (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_MODE Mode,
+ IN UINT16 *Mask, OPTIONAL
+ IN UINT16 *EdgeLevel OPTIONAL
+ )
+{
+ if (Mode == mMode) {
+ return EFI_SUCCESS;
+ }
+
+ if (Mode == Efi8259LegacyMode) {
+ //
+ // In Efi8259ProtectedMode, mask and edge/level trigger registers should
+ // be changed through this protocol, so we can track them in the
+ // corresponding module variables.
+ //
+ Interrupt8259ReadMask (&mProtectedModeMask, &mProtectedModeEdgeLevel);
+
+ if (Mask != NULL) {
+ //
+ // Update the Mask for the new mode
+ //
+ mLegacyModeMask = *Mask;
+ }
+
+ if (EdgeLevel != NULL) {
+ //
+ // Update the Edge/Level triggered mask for the new mode
+ //
+ mLegacyModeEdgeLevel = *EdgeLevel;
+ }
+
+ mMode = Mode;
+
+ //
+ // Write new legacy mode mask/trigger level
+ //
+ Interrupt8259WriteMask (mLegacyModeMask, mLegacyModeEdgeLevel);
+
+ return EFI_SUCCESS;
+ }
+
+ if (Mode == Efi8259ProtectedMode) {
+ //
+ // Save the legacy mode mask/trigger level
+ //
+ Interrupt8259ReadMask (&mLegacyModeMask, &mLegacyModeEdgeLevel);
+ //
+ // Always force Timer to be enabled after return from 16-bit code.
+ // This always insures that on next entry, timer is counting.
+ //
+ mLegacyModeMask &= 0xFFFE;
+
+ if (Mask != NULL) {
+ //
+ // Update the Mask for the new mode
+ //
+ mProtectedModeMask = *Mask;
+ }
+
+ if (EdgeLevel != NULL) {
+ //
+ // Update the Edge/Level triggered mask for the new mode
+ //
+ mProtectedModeEdgeLevel = *EdgeLevel;
+ }
+
+ mMode = Mode;
+
+ //
+ // Write new protected mode mask/trigger level
+ //
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ Translates the IRQ into a vector.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[out] Vector The vector that is assigned to the IRQ.
+
+ @retval EFI_SUCCESS The Vector that matches Irq was returned.
+ @retval EFI_INVALID_PARAMETER Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetVector (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ OUT UINT8 *Vector
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Irq <= Efi8259Irq7) {
+ *Vector = (UINT8) (mMasterBase + Irq);
+ } else {
+ *Vector = (UINT8) (mSlaveBase + (Irq - Efi8259Irq8));
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Enables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
+
+ @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EnableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ IN BOOLEAN LevelTriggered
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ mProtectedModeMask = (UINT16) (mProtectedModeMask & ~(1 << Irq));
+ if (LevelTriggered) {
+ mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel | (1 << Irq));
+ } else {
+ mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq));
+ }
+
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Disables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259DisableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ mProtectedModeMask = (UINT16) (mProtectedModeMask | (1 << Irq));
+
+ mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq));
+
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Reads the PCI configuration space to get the interrupt number that is assigned to the card.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] PciHandle PCI function for which to return the vector.
+ @param[out] Vector IRQ number that corresponds to the interrupt line.
+
+ @retval EFI_SUCCESS The interrupt line value was read successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetInterruptLine (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT UINT8 *Vector
+ )
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 InterruptLine;
+ EFI_STATUS Status;
+
+ Status = gBS->HandleProtocol (
+ PciHandle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ PCI_INT_LINE_OFFSET,
+ 1,
+ &InterruptLine
+ );
+ //
+ // Interrupt line is same location for standard PCI cards, standard
+ // bridge and CardBus bridge.
+ //
+ *Vector = InterruptLine;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Issues the End of Interrupt (EOI) commands to PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq The interrupt for which to issue the EOI command.
+
+ @retval EFI_SUCCESS The EOI command was issued.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EndOfInterrupt (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Irq >= Efi8259Irq8) {
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);
+ }
+
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Driver Entry point.
+
+ @param[in] ImageHandle ImageHandle of the loaded driver.
+ @param[in] SystemTable Pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS One or more of the drivers returned a success code.
+ @retval !EFI_SUCCESS Error installing Legacy 8259 Protocol.
+
+**/
+EFI_STATUS
+EFIAPI
+Install8259 (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_8259_IRQ Irq;
+
+ //
+ // Initialze mask values from PCDs
+ //
+ mLegacyModeMask = PcdGet16 (Pcd8259LegacyModeMask);
+ mLegacyModeEdgeLevel = PcdGet16 (Pcd8259LegacyModeEdgeLevel);
+
+ //
+ // Clear all pending interrupt
+ //
+ for (Irq = Efi8259Irq0; Irq <= Efi8259Irq15; Irq++) {
+ Interrupt8259EndOfInterrupt (&mInterrupt8259, Irq);
+ }
+
+ //
+ // Set the 8259 Master base to 0x68 and the 8259 Slave base to 0x70
+ //
+ Status = Interrupt8259SetVectorBase (&mInterrupt8259, PROTECTED_MODE_BASE_VECTOR_MASTER, PROTECTED_MODE_BASE_VECTOR_SLAVE);
+
+ //
+ // Set all 8259 interrupts to edge triggered and disabled
+ //
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ //
+ // Install 8259 Protocol onto a new handle
+ //
+ Status = gBS->InstallProtocolInterface (
+ &m8259Handle,
+ &gEfiLegacy8259ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mInterrupt8259
+ );
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h
new file mode 100644
index 0000000000..3bf31067fa
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h
@@ -0,0 +1,68 @@
+/** @file
+ Header file of OVMF instance of PciHostBridgeLib.
+
+ Copyright (c) 2016 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/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
new file mode 100644
index 0000000000..8c6de3dca6
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -0,0 +1,50 @@
+## @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/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ PciLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h
new file mode 100644
index 0000000000..1fb031b752
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h
@@ -0,0 +1,156 @@
+/** @file
+ Platform BDS customizations include file.
+
+ Copyright (c) 2006 - 2017 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
+ );
+
+#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644
index 0000000000..55da35e87d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -0,0 +1,69 @@
+## @file
+# Platform BDS customizations library.
+#
+# Copyright (c) 2007 - 2018 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/SimicsOpenBoardPkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ UefiBootManagerLib
+ BootLogoLib
+ DevicePathLib
+ PciLib
+ NvVarsFileLib
+ LoadLinuxLib
+ UefiLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent
+ gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+ gSimicsX58PkgTokenSpaceGuid.PcdShellFile
+
+[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/Overrides/MdeModulePkg/Logo/Logo.bmp b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/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/Overrides/MdeModulePkg/Logo/Logo.idf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
new file mode 100644
index 0000000000..1f79332020
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
@@ -0,0 +1,10 @@
+// /** @file
+// Platform Logo image definition file.
+//
+// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#image IMG_LOGO Logo.bmp
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
new file mode 100644
index 0000000000..3380f3c1d5
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
@@ -0,0 +1,28 @@
+## @file
+# The default logo bitmap picture shown on setup screen, which is corresponding to gEfiDefaultBmpLogoGuid.
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Logo
+ MODULE_UNI_FILE = Logo.uni
+ FILE_GUID = 7BB28B99-61BB-11D5-9A5D-0090273FC14D
+ 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 ARM AARCH64
+#
+
+[Binaries]
+ BIN|Logo.bmp|*
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ LogoExtra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
new file mode 100644
index 0000000000..9d1bbaffa9
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
@@ -0,0 +1,16 @@
+// /** @file
+// The default logo bitmap picture shown on setup screen, which is corresponding to gEfiDefaultBmpLogoGuid.
+//
+// This module provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid.
+//
+// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid."
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf
new file mode 100644
index 0000000000..01102b138f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf
@@ -0,0 +1,55 @@
+## @file
+# The default logo bitmap picture shown on setup screen.
+#
+# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LogoDxe
+ MODULE_UNI_FILE = LogoDxe.uni
+ FILE_GUID = F74D20EE-37E7-48FC-97F7-9B1047749C69
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeLogo
+#
+# This flag specifies whether HII resource section is generated into PE image.
+#
+ UEFI_HII_RESOURCE_SECTION = TRUE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ Logo.bmp
+ Logo.c
+ Logo.idf
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ DebugLib
+
+[Protocols]
+ gEfiHiiDatabaseProtocolGuid ## CONSUMES
+ gEfiHiiImageExProtocolGuid ## CONSUMES
+ gEfiHiiPackageListProtocolGuid ## PRODUCES CONSUMES
+ gEdkiiPlatformLogoProtocolGuid ## PRODUCES
+
+[Depex]
+ gEfiHiiDatabaseProtocolGuid AND
+ gEfiHiiImageExProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ LogoDxeExtra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni
new file mode 100644
index 0000000000..9635701b60
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni
@@ -0,0 +1,16 @@
+// /** @file
+// The default logo bitmap picture shown on setup screen.
+//
+// This module provides the default logo bitmap picture shown on setup screen, through EDKII Platform Logo protocol.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides the default logo bitmap picture shown on setup screen."
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module provides the default logo bitmap picture shown on setup screen, through EDKII Platform Logo protocol."
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni
new file mode 100644
index 0000000000..c6ea34b81d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Logo Localized Strings and Content
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Logo Image File"
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni
new file mode 100644
index 0000000000..041179fb75
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Logo Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Logo Image File"
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
new file mode 100644
index 0000000000..e5ca95e20e
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
@@ -0,0 +1,40 @@
+## @file
+# An instance of the PCI Library that is based on both the PCI CF8 Library and
+# the PCI Express Library.
+#
+# This PciLib instance caches the SimicsX58 platform type (X58-ICH10) in
+# its entry point function, then delegates function calls to one of the
+# PciCf8Lib or PciExpressLib "backends" as appropriate.
+#
+# Copyright (C) 2016, Red Hat, Inc.
+# Copyright (c) 2007 - 2014 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxePciLibX58Ich10
+ FILE_GUID = FC214B5D-B5B5-4E54-9B28-5E94532E5E2A
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PciLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION
+ CONSTRUCTOR = InitializeConfigAccessMethod
+
+# VALID_ARCHITECTURES = IA32 X64
+
+[Sources]
+ PciLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ PcdLib
+ PciCf8Lib
+ PciExpressLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
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..2deb2a88eb
--- /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) 2017 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..b4b52b6622
--- /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) 2017 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..8370559016
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
@@ -0,0 +1,73 @@
+## @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/SimicsOpenBoardPkg.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
+ gSimicsX58PkgTokenSpaceGuid.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..cb2a60d827
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm
@@ -0,0 +1,281 @@
+;------------------------------------------------------------------------------
+; @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
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
new file mode 100644
index 0000000000..a9673f9c87
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
@@ -0,0 +1,218 @@
+/** @file
+ Driver implementing the Tiano Legacy 8259 Protocol
+
+Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _8259_H__
+#define _8259_H__
+
+#include <Protocol/Legacy8259.h>
+#include <Protocol/PciIo.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+// 8259 Hardware definitions
+
+#define LEGACY_MODE_BASE_VECTOR_MASTER 0x08
+#define LEGACY_MODE_BASE_VECTOR_SLAVE 0x70
+
+#define PROTECTED_MODE_BASE_VECTOR_MASTER 0x68
+#define PROTECTED_MODE_BASE_VECTOR_SLAVE 0x70
+
+#define LEGACY_8259_CONTROL_REGISTER_MASTER 0x20
+#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
+#define LEGACY_8259_CONTROL_REGISTER_SLAVE 0xA0
+#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
+
+#define LEGACY_8259_EOI 0x20
+
+// Protocol Function Prototypes
+
+/**
+ Sets the base address for the 8259 master and slave PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
+ @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing to the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetVectorBase (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT8 MasterBase,
+ IN UINT8 SlaveBase
+ );
+
+/**
+ Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ OUT UINT16 *LegacyMask, OPTIONAL
+ OUT UINT16 *LegacyEdgeLevel, OPTIONAL
+ OUT UINT16 *ProtectedMask, OPTIONAL
+ OUT UINT16 *ProtectedEdgeLevel OPTIONAL
+ );
+
+/**
+ Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT16 *LegacyMask, OPTIONAL
+ IN UINT16 *LegacyEdgeLevel, OPTIONAL
+ IN UINT16 *ProtectedMask, OPTIONAL
+ IN UINT16 *ProtectedEdgeLevel OPTIONAL
+ );
+
+/**
+ Sets the mode of the PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Mode 16-bit real or 32-bit protected mode.
+ @param[in] Mask The value with which to set the interrupt mask.
+ @param[in] EdgeLevel The value with which to set the edge/level mask.
+
+ @retval EFI_SUCCESS The mode was set successfully.
+ @retval EFI_INVALID_PARAMETER The mode was not set.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMode (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_MODE Mode,
+ IN UINT16 *Mask, OPTIONAL
+ IN UINT16 *EdgeLevel OPTIONAL
+ );
+
+/**
+ Translates the IRQ into a vector.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[out] Vector The vector that is assigned to the IRQ.
+
+ @retval EFI_SUCCESS The Vector that matches Irq was returned.
+ @retval EFI_INVALID_PARAMETER Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetVector (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ OUT UINT8 *Vector
+ );
+
+/**
+ Enables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
+
+ @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EnableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ IN BOOLEAN LevelTriggered
+ );
+
+/**
+ Disables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259DisableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ );
+
+/**
+ Reads the PCI configuration space to get the interrupt number that is assigned to the card.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] PciHandle PCI function for which to return the vector.
+ @param[out] Vector IRQ number that corresponds to the interrupt line.
+
+ @retval EFI_SUCCESS The interrupt line value was read successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetInterruptLine (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT UINT8 *Vector
+ );
+
+/**
+ Issues the End of Interrupt (EOI) commands to PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq The interrupt for which to issue the EOI command.
+
+ @retval EFI_SUCCESS The EOI command was issued.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EndOfInterrupt (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ );
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
new file mode 100644
index 0000000000..e66b21c914
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
@@ -0,0 +1,46 @@
+## @file
+# 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
+#
+# Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Legacy8259
+ MODULE_UNI_FILE = Legacy8259.uni
+ FILE_GUID = 79CA4208-BBA1-4a9a-8456-E1E66A81484E
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = Install8259
+
+[Sources]
+ 8259.c
+ 8259.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ PcAtChipsetPkg/PcAtChipsetPkg.dec
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ DebugLib
+ UefiDriverEntryPoint
+ IoLib
+ PcdLib
+
+[Protocols]
+ gEfiLegacy8259ProtocolGuid ## PRODUCES
+ gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMES
+
+[Pcd]
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask ## CONSUMES
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel ## CONSUMES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ Legacy8259Extra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
new file mode 100644
index 0000000000..d035292419
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
@@ -0,0 +1,16 @@
+// /** @file
+// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
+//
+// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
+//
+// Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "8259 Interrupt Controller driver that provides Legacy 8259 protocol"
+
+#string STR_MODULE_DESCRIPTION #language en-US "8259 Interrupt Controller driver that provides Legacy 8259 protocol."
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
new file mode 100644
index 0000000000..ee43f6923c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Legacy8259 Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Legacy 8259 Interrupt Controller DXE Driver"
+
+
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [edk2-platform patch 6/7] SimicsOpenBoardPkg: Add board module for QSP Build tip
2019-08-09 22:46 [edk2-platform patch 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
` (4 preceding siblings ...)
2019-08-09 22:46 ` [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform David Wei
@ 2019-08-09 22:46 ` David Wei
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform David Wei
6 siblings, 1 reply; 37+ messages in thread
From: David Wei @ 2019-08-09 22:46 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>
Contributed-under: TianoCore Contribution Agreement 1.0
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 +++++
.../BoardX58ICH10/GitEdk2X58ICH10.bat | 75 +++++
.../BoardInitLib/PeiBoardInitPostMemLib.inf | 36 +++
.../Library/BoardInitLib/PeiBoardInitPreMemLib.inf | 38 +++
.../Library/BoardInitLib/PeiX58ICH10InitLib.h | 16 ++
.../BoardX58ICH10/PlatformPkgBuildOption.dsc | 89 ++++++
.../BoardX58ICH10/PlatformPkgConfig.dsc | 56 ++++
.../BoardX58ICH10/PlatformPkgPcd.dsc | 283 +++++++++++++++++++
.../BoardX58ICH10/SimicsX58Pkg.fdf.inc | 48 ++++
.../BoardX58ICH10/SimicsX58PkgIa32X64.dsc | 244 +++++++++++++++++
.../BoardX58ICH10/SimicsX58PkgIa32X64.fdf | 303 +++++++++++++++++++++
.../BoardX58ICH10/VarStore.fdf.inc | 53 ++++
.../Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat | 139 ++++++++++
.../BoardX58ICH10/build_config.cfg | 31 +++
.../SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat | 198 ++++++++++++++
20 files changed, 2000 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/GitEdk2X58ICH10.bat
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/PlatformPkgBuildOption.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58Pkg.fdf.inc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.dsc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.fdf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/VarStore.fdf.inc
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
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..29df3d41ee
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiBoardInitPostMemLib.c
@@ -0,0 +1,44 @@
+/** @file
+ Copyright (c) 2018 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..228fd696df
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiBoardInitPreMemLib.c
@@ -0,0 +1,110 @@
+/** @file
+ Copyright (c) 2018 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..7305ce3181
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX58ICH10Detect.c
@@ -0,0 +1,26 @@
+/** @file
+ Copyright (c) 2018 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..002f63a434
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX58ICH10InitPostMemLib.c
@@ -0,0 +1,34 @@
+/** @file
+ Copyright (c) 2018 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..9f0dc91c8a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX58ICH10InitPreMemLib.c
@@ -0,0 +1,111 @@
+/** @file
+ Copyright (c) 2018 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 <IndustryStandard/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..394875f205
--- /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 + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize + 16 + gSimicsX58PkgTokenSpaceGuid.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) + gSimicsX58PkgTokenSpaceGuid.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 gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd = $(DECOMP_SCRATCH_BASE) + $(DECOMP_SCRATCH_SIZE)
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
new file mode 100644
index 0000000000..48e9c6b09d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
@@ -0,0 +1,75 @@
+@echo off
+@REM @file
+@REM Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
+@REM
+@REM SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM
+
+@echo off
+
+pushd ..\..\..\..\..\
+
+@REM Set WORKSPACE environment.
+set WORKSPACE=%cd%
+echo.
+echo Set WORKSPACE as: %WORKSPACE%
+echo.
+
+@REM Check whether Git has been installed and been added to system path.
+git --help >nul 2>nul
+if %ERRORLEVEL% NEQ 0 (
+ echo.
+ echo The 'git' command is not recognized.
+ echo Please make sure that Git is installed and has been added to system path.
+ echo.
+ goto :EOF
+)
+
+@REM Create the Conf directory under WORKSPACE
+if not exist %WORKSPACE%\Conf (
+ mkdir Conf
+)
+
+@REM Set other environments.
+@REM Basic Rule:
+@REM Platform override Silicon override Core
+@REM Source override Binary
+
+set PACKAGES_PATH=%WORKSPACE%\edk2-platforms\Platform\Intel;%WORKSPACE%\edk2-platforms\Silicon\Intel;%WORKSPACE%\edk2-platforms\Drivers;%WORKSPACE%\edk2-non-osi\Silicon\Intel;%WORKSPACE%\edk2;%WORKSPACE%
+
+set EDK_TOOLS_BIN=%WORKSPACE%\edk2-BaseTools-win32
+
+@if not defined PYTHON_HOME (
+ @if exist C:\Python27 (
+ set PYTHON_HOME=C:\Python27
+ )
+)
+
+set EDK_SETUP_OPTION=
+@rem if python is installed, disable the binary base tools.
+if defined PYTHON_HOME (
+ set EDK_TOOLS_BIN=
+ set EDK_SETUP_OPTION=Rebuild
+)
+pushd %WORKSPACE%\edk2
+call edksetup.bat %EDK_SETUP_OPTION%
+popd
+
+set openssl_path=%WORKSPACE%
+
+popd
+
+goto :EOF
+
+:Help
+echo.
+echo Usage:
+echo GitEdk2.bat [-w Workspace_Directory] (optional) [-b Branch_Name] (optional)
+echo.
+echo -w A absolute/relative path to be the workspace.
+echo Default value is the current directory.
+echo.
+echo -b The branch name of the repository. Currently, only master, udk2015,
+echo trunk (same as master) and bp13 (same as udk2015) are supported.
+echo Default value is master.
+echo.
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..542b53547f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiBoardInitPostMemLib.inf
@@ -0,0 +1,36 @@
+## @file
+#
+# Copyright (c) 2018 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..ab1286602b
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiBoardInitPreMemLib.inf
@@ -0,0 +1,38 @@
+## @file
+#
+# Copyright (c) 2018 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/SimicsOpenBoardPkg.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..996679e8f5
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX58ICH10InitLib.h
@@ -0,0 +1,16 @@
+/** @file
+ Copyright (c) 2018 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/PlatformPkgBuildOption.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOption.dsc
new file mode 100644
index 0000000000..8bce3c7a4f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOption.dsc
@@ -0,0 +1,89 @@
+## @file
+#
+# Copyright (c) 2018 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 CRB_EDKII_BUILD_OPTIONS = -D CRB_FLAG
+ DEFINE EDKII_CPU_BUILD_OPTIONS = -D PURLEY_FLAG
+ DEFINE TRAD_BUILD_OPTION = -D TRAD_FLAG=1
+ DEFINE SUS_WELL_RESTORE_BUILD_OPTION = -D SUS_WELL_RESTORE=1
+ DEFINE PCH_BUILD_OPTION = -D PCH_SERVER_BIOS_FLAG=1
+ DEFINE SERVER_BUILD_OPTION = -D SERVER_BIOS_FLAG=1
+ DEFINE PCH_PKG_OPTIONS = -D PCH_SPT
+ DEFINE MAX_SOCKET_OPTIONS = -D MAX_SOCKET=2
+
+ DEFINE EDKII_ALL_PPO_OPTIONS = $(EDKII_CPU_BUILD_OPTIONS)
+ DEFINE PCH_BIOS_BUILD_OPTIONS = $(TRAD_BUILD_OPTION) $(ULT_BUILD_OPTION) $(PCH_BUILD_OPTION) $(SUS_WELL_RESTORE_BUILD_OPTION) $(SERVER_BUILD_OPTION)
+ DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS = $(CRB_EDKII_BUILD_OPTIONS) $(PCH_BIOS_BUILD_OPTIONS) $(PCH_PKG_OPTIONS) $(EDKII_ALL_PPO_OPTIONS) $(SPARING_SCRATCHPAD_OPTION) $(TRACE_HUB_DEBUG_BUILD_OPTIONS) $(TRACE_HUB_INIT_BUILD_OPTIONS) $(MAX_SOCKET_OPTIONS) -D EFI_PCI_IOV_SUPPORT -D WHEA_SUPPORT -D SKX_HOST -D CLX_HOST
+
+!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/PlatformPkgConfig.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
new file mode 100644
index 0000000000..f0ab846290
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
@@ -0,0 +1,56 @@
+## @file
+#
+# Copyright (c) 2018 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/PlatformPkgPcd.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
new file mode 100644
index 0000000000..dc70adee34
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
@@ -0,0 +1,283 @@
+## @file
+#
+# Copyright (c) 2018 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
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress|0xFFE00000
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize|0x00200000
+
+[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
+
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase|0x0
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize|0x0
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base|0x0
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size|0x0
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base|0x0
+ gSimicsX58PkgTokenSpaceGuid.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/SimicsX58Pkg.fdf.inc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58Pkg.fdf.inc
new file mode 100644
index 0000000000..f42e8b0e0e
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58Pkg.fdf.inc
@@ -0,0 +1,48 @@
+## @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 gSimicsX58PkgTokenSpaceGuid.PcdSimicsFdBaseAddress = $(FW_BASE_ADDRESS)
+SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareFdSize = $(FW_SIZE)
+SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareBlockSize = $(BLOCK_SIZE)
+
+SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase = $(FW_BASE_ADDRESS)
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize = 0xE000
+
+SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase = gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize = $(BLOCK_SIZE)
+
+SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase = gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize = $(BLOCK_SIZE)
+
+SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase = gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = 0x10000
+
+DEFINE MEMFD_BASE_ADDRESS = 0x800000
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.dsc b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.dsc
new file mode 100644
index 0000000000..66ac16a940
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.dsc
@@ -0,0 +1,244 @@
+## @file
+#
+# Copyright (c) 2018 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)/SimicsX58PkgIa32X64.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)/PlatformPkgConfig.dsc
+ !include MinPlatformPkg/Include/Dsc/CoreCommonLib.dsc
+ !include $(PCH_PKG)/PchCommonLib.dsc
+
+[LibraryClasses]
+ ReportFvLib|MinPlatformPkg/PlatformInit/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
+ LoadLinuxLib|$(BOARD_PKG)/Library/LoadLinuxLib/LoadLinuxLib.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
+[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_CORE]
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+ PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+ PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+ PlatformBootManagerLib|$(BOARD_PKG)/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+ PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
+
+[LibraryClasses.common.UEFI_APPLICATION]
+ PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
+
+[LibraryClasses.common.DXE_SMM_DRIVER]
+ PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
+ SpiFlashCommonLib|$(PCH_PKG)/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
+
+[LibraryClasses.common.SMM_CORE]
+ PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
+
+ !include $(BOARD_PKG)/$(BOARD_NAME)/PlatformPkgPcd.dsc
+
+[Components.IA32]
+ !include $(SKT_PKG)/SktPei.dsc
+ !include MinPlatformPkg/Include/Dsc/CorePeiInclude.dsc
+
+ $(BOARD_PKG)/PlatformPei/PlatformPei.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
+ $(BOARD_PKG)/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
+ !include AdvancedFeaturePkg/Include/Dsc/CoreAdvancedDxeInclude.dsc
+
+ MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+ $(BOARD_PKG)/Overrides/MdeModulePkg/Logo/LogoDxe.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)/PlatformDxe/Platform.inf
+ MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+ MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.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)/Overrides/MdeModulePkg/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)/PlatformPkgBuildOption.dsc
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.fdf b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.fdf
new file mode 100644
index 0000000000..d6c381a515
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.fdf
@@ -0,0 +1,303 @@
+## @file
+#
+# Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+!include SimicsX58Pkg.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
+gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase|gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesSize
+
+0x006000|0x001000
+gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase|gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize
+
+0x007000|0x001000
+gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+
+0x010000|0x008000
+gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
+
+0x020000|0x0E0000
+gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase|gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
+FV = FvPreMemory
+
+0x100000|0xA00000
+gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase|gSimicsX58PkgTokenSpaceGuid.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
+
+!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)/PchPreMemoryInclude.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)/PlatformPei/PlatformPei.inf
+!include $(SKT_PKG)/SktPostMemoryInclude.fdf
+!include $(PCH_PKG)/PchPostMemoryInclude.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
+INF $(BOARD_PKG)/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
+!include $(SKT_PKG)/SktUefiBootInclude.fdf
+!include $(PCH_PKG)/PchUefiBootInclude.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 $(BOARD_PKG)/Overrides/MdeModulePkg/Logo/LogoDxe.inf
+INF MinPlatformPkg/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
+INF MinPlatformPkg/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
+INF $(BOARD_PKG)/PlatformDxe/Platform.inf
+
+INF ShellPkg/Application/Shell/Shell.inf
+
+#
+# Network modules
+#
+FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 {
+ SECTION PE32 = SimicsICH10SiliconBinPkg/UndiBinary/GigUndiDxe.efi
+ SECTION UI = "IntelIch10UNDI"
+}
+!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/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/bld.bat b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
new file mode 100644
index 0000000000..efce310dfe
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
@@ -0,0 +1,139 @@
+@echo off
+@REM @file
+@REM Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
+@REM
+@REM SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM
+
+@echo off
+
+REM Run setlocal to take a snapshot of the environment variables. endlocal is called to restore the environment.
+setlocal
+set SCRIPT_ERROR=0
+
+REM ---- Do NOT use :: for comments Inside of code blocks() ----
+
+::**********************************************************************
+:: Initial Setup
+::**********************************************************************
+
+:parseCmdLine
+if "%1"=="" goto :argumentCheck
+
+if /I "%1"=="debug" set TARGET=DEBUG
+if /I "%1"=="release" set TARGET=RELEASE
+
+if /I "%1"=="cleantree" (
+ set BUILD_TYPE=cleantree
+ call :cleantree
+ goto :EOF
+)
+
+shift
+GOTO :parseCmdLine
+
+:argumentCheck:
+
+if /I "%TARGET%" == "" (
+ echo Info: debug/release argument is empty, use DEBUG as default
+ set TARGET=DEBUG
+)
+
+REM Art to notify which board you're working on
+echo.
+type logo.txt
+echo.
+
+::
+:: Build configuration
+::
+set BUILD_REPORT_FLAGS=
+set BUILD_CMD_LINE=
+set BUILD_LOG=%WORKSPACE%\Build\BuildSrc\build.log
+set BUILD_REPORT=%WORKSPACE%\Build\BuildSrc\BuildReport.txt
+
+del %BUILD_LOG% *.efi *.log 2>NUL
+
+echo --------------------------------------------------------------------------------------------
+echo.
+echo QSP Build Start
+echo.
+echo --------------------------------------------------------------------------------------------
+
+
+:doPreBuild
+echo.
+echo --------------------------------------------------------------------
+echo.
+echo Prebuild Start
+echo.
+echo --------------------------------------------------------------------
+call prebuild.bat
+if %SCRIPT_ERROR% NEQ 0 EXIT /b %ERRORLEVEL%
+
+echo --------------------------------------------------------------------
+echo.
+echo Prebuild End
+echo.
+echo --------------------------------------------------------------------
+if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
+timeout 1
+
+:buildBios
+set BUILD_CMD_LINE=%BUILD_CMD_LINE% -D MAX_SOCKET=%MAX_SOCKET% -y %BUILD_REPORT%
+echo --------------------------------------------------------------------
+echo.
+echo Build Start
+echo.
+echo --------------------------------------------------------------------
+echo.
+echo build %BUILD_CMD_LINE% --log=%BUILD_LOG% %BUILD_REPORT_FLAGS%
+call build %BUILD_CMD_LINE% --log=%BUILD_LOG% %BUILD_REPORT_FLAGS%
+echo --------------------------------------------------------------------
+echo.
+echo Build End
+echo.
+echo --------------------------------------------------------------------
+if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
+timeout 1
+
+:postBuild
+
+echo --------------------------------------------------------------------
+echo.
+echo PostBuild Start
+echo.
+echo --------------------------------------------------------------------
+echo.
+REM call postbuild.bat
+if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
+timeout 1
+echo --------------------------------------------------------------------
+echo.
+echo PostBuild End
+echo.
+echo --------------------------------------------------------------------
+
+echo %date% %time%
+echo.
+
+echo --------------------------------------------------------------------------------------------
+echo.
+echo QSP Build End
+echo.
+echo --------------------------------------------------------------------------------------------
+
+:done
+endlocal & EXIT /b %SCRIPT_ERROR%
+
+::--------------------------------------------------------
+::-- Function section starts below here
+::--------------------------------------------------------
+:cleantree
+choice /t 3 /d y /m "Confirm: clean tree of intermediate files created in tree during build"
+if %ERRORLEVEL% EQU 2 goto :EOF
+goto :EOF
+
+
+:ErrorHandler:
+echo Error handler
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
new file mode 100644
index 0000000000..ad3ae229e8
--- /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 = WORKSPACE_PLATFORM_BIN
+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/SimicsX58PkgIa32X64.dsc
+BOARD_PKG_PCD_DSC = SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.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
diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
new file mode 100644
index 0000000000..666332e2d4
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
@@ -0,0 +1,198 @@
+@echo off
+@REM @file
+@REM Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
+@REM
+@REM SPDX-License-Identifier: BSD-2-Clause-Patent
+@REM
+
+@set SCRIPT_ERROR=0
+
+set /a prebuildstep=0
+
+call :check_BuildTools
+if %SCRIPT_ERROR% NEQ 0 GOTO :done
+
+call :setBuildEnv
+if %SCRIPT_ERROR% NEQ 0 GOTO :done
+
+call :createTargetTxt
+if %SCRIPT_ERROR% NEQ 0 GOTO :done
+
+REM call :genPlatformOffsetHeaderFile
+REM if %SCRIPT_ERROR% NEQ 0 GOTO :done
+
+:prebuildFinish
+echo.
+echo ACTIVE_PLATFORM = %WORKSPACE%\edk2-platforms\Platform\Intel\%BOARD_PKG%\%BOARD_NAME%\SimicsX58PkgIa32X64.dsc
+echo EDK_TOOLS_PATH = %EDK_TOOLS_PATH%
+echo TARGET = %TARGET%
+echo TARGET_ARCH = IA32 X64
+echo TOOL_CHAIN_TAG = %TOOL_CHAIN_TAG%
+echo WORKSPACE = %WORKSPACE%
+echo PACKAGES_PATH = %PACKAGES_PATH%
+echo MAX_CONCURRENT_THREAD_NUMBER = %BUILD_MAX_CON_THREAD_NUM%
+echo.
+echo Build Path = %OUTPUT_DIR%
+echo.
+
+REM Remove environment variable because it's no longer needed.
+set BUILD_MAX_CON_THREAD_NUM=
+
+:done
+REM Use done label to exit batch file and run any final steps; GOTO :EOF immediately exits.
+EXIT /B %SCRIPT_ERROR%
+
+::--------------------------------------------------------
+::-- Function section starts below here
+::--------------------------------------------------------
+
+:cleanup_check_VSTools
+set COMPILER_VERSION_STRING=
+del cloutput.txt > nul
+REM cleanup_check_VSTools is called below. When a label is called, 'GOTO :EOF' is used to return to caller.
+GOTO :EOF
+
+:check_BuildTools
+echo PreBuild.%prebuildstep% check_BuildTools
+echo ..VSTools
+set /a prebuildstep=%prebuildstep%+1
+set TOOL_CHAIN_TAG=
+@if not defined TOOL_CHAIN_TAG (
+ echo.
+ echo Prebuild: TOOL_CHAIN_TAG is not set before
+ echo.
+
+ @if defined VS140COMNTOOLS (
+ echo.
+ echo Set the VS2015 environment.
+ echo.
+ set CL_SEL=VS2015
+ if /I "%VS140COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio 14.0\Common7\Tools\" (
+ set TOOL_CHAIN_TAG=VS2015
+ ) else (
+ set TOOL_CHAIN_TAG=VS2015x86
+ )
+ if /I "%PROCESSOR_ARCHITECTURE%" == "AMD64" (
+ set CL_CMDLINE="%VS140COMNTOOLS:~0,-14%VC\bin\amd64\cl.exe"
+ ) else (
+ set CL_CMDLINE="%VS140COMNTOOLS:~0,-14%VC\bin\cl.exe"
+ )
+ ) else if defined VS120COMNTOOLS (
+ echo.
+ echo Set the VS2013 environment.
+ echo.
+ set CL_SEL=VS2013
+ if /I "%VS120COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio 12.0\Common7\Tools\" (
+ set TOOL_CHAIN_TAG=VS2013
+ ) else (
+ set TOOL_CHAIN_TAG=VS2013x86
+ )
+ if /I "%PROCESSOR_ARCHITECTURE%" == "AMD64" (
+ set CL_CMDLINE="%VS120COMNTOOLS:~0,-14%VC\bin\amd64\cl.exe"
+ ) else (
+ set CL_CMDLINE="%VS120COMNTOOLS:~0,-14%VC\bin\cl.exe"
+ )
+ ) else (
+ echo.
+ echo !!! ERROR !!! VS2015 or VS2013 not installed correctly. !!!
+ echo.
+ goto :ErrorExit
+ )
+)
+
+echo ..iASL
+set CHECK_PATH_IASL=%IASL_PREFIX%
+if not exist %CHECK_PATH_IASL%\iasl.exe (
+ echo.
+ echo !!! ERROR !!! Could not find iASL compiler at %CHECK_PATH_IASL%\iasl.exe. !!!
+ echo.
+ set SCRIPT_ERROR=1
+)
+set CHECK_PATH_IASL=
+
+echo ..NASM
+set CHECK_PATH_NASM=c:\NASM
+if not exist %CHECK_PATH_NASM%\nasm.exe (
+ echo.
+ echo !!! ERROR !!! Could not find NASM compiler at %CHECK_PATH_NASM%\nasm.exe. !!!
+ echo.
+ set SCRIPT_ERROR=1
+)
+set CHECK_PATH_NASM=
+
+echo ..Python
+set CHECK_PATH_PYTHON=c:\Python27
+if not exist %CHECK_PATH_PYTHON%\python.exe (
+ echo.
+ echo !!! ERROR !!! Could not find Python at %CHECK_PATH_PYTHON%\python.exe. !!!
+ echo.
+ set SCRIPT_ERROR=1
+)
+set CHECK_PATH_PYTHON=
+set PYTHON_HOME=C:\Python27
+
+GOTO :EOF
+
+:setBuildEnv
+echo PreBuild.%prebuildstep% SetBuildEnv
+set /a prebuildstep=%prebuildstep%+1
+
+@set BOARD_PKG=SimicsOpenBoardPkg
+@set BOARD_NAME=BoardX58ICH10
+@set MAX_SOCKET=2
+
+echo.
+echo BOARD_NAME=%BOARD_NAME%
+echo BOARD_PKG=%BOARD_PKG%
+echo MAX_SOCKET=%MAX_SOCKET%
+echo TARGET=%TARGET%
+
+@set OUTPUT_DIR=%WORKSPACE%\Build\BuildSrc\%BOARD_PKG%\%BOARD_NAME%\%TARGET%_%TOOL_CHAIN_TAG%
+
+if not exist %OUTPUT_DIR% mkdir %OUTPUT_DIR%
+GOTO :EOF
+
+:createTargetTxt
+echo PreBuild.%prebuildstep% CreateTargetTxt
+set /a prebuildstep=%prebuildstep%+1
+set /a BUILD_MAX_CON_THREAD_NUM = %NUMBER_OF_PROCESSORS%-1
+@REM set /a BUILD_MAX_CON_THREAD_NUM = 1
+findstr /V "ACTIVE_PLATFORM TARGET TARGET_ARCH TOOL_CHAIN_TAG BUILD_RULE_CONF MAX_CONCURRENT_THREAD_NUMBER" %WORKSPACE%\Conf\target.txt > %OUTPUT_DIR%\target.txt 2>NUL
+echo ACTIVE_PLATFORM = %WORKSPACE%/edk2-platforms/Platform/Intel/%BOARD_PKG%/%BOARD_NAME%/SimicsX58PkgIa32X64.dsc >> %OUTPUT_DIR%\target.txt
+echo TARGET = %TARGET% >> %OUTPUT_DIR%\target.txt
+echo TARGET_ARCH = IA32 X64 >> %OUTPUT_DIR%\target.txt
+echo TOOL_CHAIN_TAG = %TOOL_CHAIN_TAG% >> %OUTPUT_DIR%\target.txt
+echo BUILD_RULE_CONF = Conf/build_rule.txt >> %OUTPUT_DIR%\target.txt
+echo MAX_CONCURRENT_THREAD_NUMBER = %BUILD_MAX_CON_THREAD_NUM% >> %OUTPUT_DIR%\target.txt
+if exist %WORKSPACE%\Conf\target.txt (
+ del /f %WORKSPACE%\Conf\target.txt
+)
+move /Y %OUTPUT_DIR%\target.txt %WORKSPACE%\Conf\ > nul
+if not exist %OUTPUT_DIR%\X64 mkdir %OUTPUT_DIR%\X64
+GOTO :EOF
+
+
+:genPlatformOffsetHeaderFile
+echo.
+echo PreBuild.%prebuildstep% GenPlatformOffsetHeaderFile
+set /a prebuildstep=%prebuildstep%+1
+
+echo Info: re-generating PlatformOffset header files
+
+set PRE_BUILD_CMD_LINE=%BUILD_CMD_LINE% -D MAX_SOCKET=%MAX_SOCKET%
+set PRE_BUILD_LOG=%WORKSPACE%\Build\BuildSrc\prebuild.log
+set PRE_BUILD_REPORT=%WORKSPACE%\Build\BuildSrc\preBuildReport.txt
+
+echo build %PRE_BUILD_CMD_LINE% -m %BOARD_PKG%\Acpi\BoardAcpiDxe\Dsdt.inf -y %PRE_BUILD_REPORT% --log=%PRE_BUILD_LOG%
+call build %PRE_BUILD_CMD_LINE% -m %BOARD_PKG%\Acpi\BoardAcpiDxe\Dsdt.inf -y %PRE_BUILD_REPORT% --log=%PRE_BUILD_LOG%
+if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
+
+@REM PSYS == FIX0
+@REM MCTL == FIX8
+set AML_FILTER="\"PSYS\" .MCTL\" .FIX[0-9,A-Z]\""
+echo AML_FILTER=%AML_FILTER%
+%WORKSPACE%\edk2-platforms\Platform\Intel\MinPlatformPkg\Tools\AmlGenOffset\AmlGenOffset.py -d --aml_filter %AML_FILTER% -o %WORKSPACE%\edk2-platforms\Platform\Intel\%BOARD_PKG%\Acpi\BoardAcpiDxe\AmlOffsetTable.c %OUTPUT_DIR%\X64\PurleyOpenBoardPkg\Acpi\BoardAcpiDxe\DSDT\OUTPUT\Dsdt\WFPPlatform.offset.h
+echo.
+echo GenOffset done
+
+GOTO :EOF
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform
2019-08-09 22:46 [edk2-platform patch 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
` (5 preceding siblings ...)
2019-08-09 22:46 ` [edk2-platform patch 6/7] SimicsOpenBoardPkg: Add board module for QSP Build tip David Wei
@ 2019-08-09 22:46 ` David Wei
2019-08-15 19:28 ` Nate DeSimone
` (2 more replies)
6 siblings, 3 replies; 37+ messages in thread
From: David Wei @ 2019-08-09 22:46 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
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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
Platform/Intel/build.cfg | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg
index fc6e4fe824..2ebe09a632 100644
--- a/Platform/Intel/build.cfg
+++ b/Platform/Intel/build.cfg
@@ -54,3 +54,5 @@ NUMBER_OF_PROCESSORS = 0
KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
+WhiskeylakeURvp = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
+BoardX58ICH10 = SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10
2019-08-09 22:46 ` [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10 David Wei
@ 2019-08-13 2:01 ` Nate DeSimone
2019-08-15 8:39 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2 siblings, 0 replies; 37+ messages in thread
From: Nate DeSimone @ 2019-08-13 2:01 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
Hi David,
I would prefer if we follow Pascal casing and rename this package to SimicsIch10Pkg (instead of SimicsICH10Pkg).
Also, I think it would be good if we can also add owners for the new packages to the Maintainers.txt file. (SimicsIch10SiliconBinPkg, SimicsX58SktPkg, SimicsIch10Pkg, and SimicsOpenBoardPkg).
Thanks,
Nate
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 9, 2019 3:47 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-platform patch 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>
Contributed-under: TianoCore Contribution Agreement 1.0
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 | 22 +
.../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 +++++++
.../IncludePrivate/Library/PchSpiCommonLib.h | 396 +++++++++
.../Library/ResetSystemLib/ResetSystemLib.inf | 34 +
.../SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf | 52 ++
.../BasePchSpiCommonLib/BasePchSpiCommonLib.inf | 33 +
Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc | 12 +
.../Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf | 9 +
.../Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf | 9 +
.../Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf | 13 +
.../SmmControl/RuntimeDxe/SmmControl2Dxe.inf | 59 ++
Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpi.h | 23 +
Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpiSmm.inf | 44 +
25 files changed, 4152 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/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/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/PchCommonLib.dsc
create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
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..46355e191c
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,137 @@
+/** @file
+ Reset System Library functions for OVMF
+
+ Copyright (c) 2006 - 2016 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 <IndustryStandard/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..3d4e24eac6
--- /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) 2017 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..1e5cd0d744
--- /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) 2017 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..77fb76d7cd
--- /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) 2017 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 <IndustryStandard/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..8fb4947b1a
--- /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 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/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..19eb469657
--- /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) 2017 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..f9d340d6df
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/ICH10Pkg.dec
@@ -0,0 +1,22 @@
+## @file
+# Copyright (c) 2014 - 2016 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}}
diff --git a/Silicon/Intel/SimicsICH10Pkg/Include/Library/SpiFlashCommonLib.h b/Silicon/Intel/SimicsICH10Pkg/Include/Library/SpiFlashCommonLib.h
new file mode 100644
index 0000000000..c36360bcb0
--- /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) 2017 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..552ce28d8c
--- /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) 2017 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..d503d130c8
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/Include/PchLimits.h
@@ -0,0 +1,94 @@
+/** @file
+ Build time limits of PCH resources.
+
+ Copyright (c) 2017 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..00139fc230
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/Include/PchReservedResources.h
@@ -0,0 +1,60 @@
+/** @file
+ PCH preserved MMIO resource definitions.
+
+ Copyright (c) 2017 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..cb5f26c47b
--- /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) 2017 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..e08721f405
--- /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) 2017 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..a727aae927
--- /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) 2017 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/IncludePrivate/Library/PchSpiCommonLib.h b/Silicon/Intel/SimicsICH10Pkg/IncludePrivate/Library/PchSpiCommonLib.h
new file mode 100644
index 0000000000..5bdec96197
--- /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) 2017 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..4af462da47
--- /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 - 2018 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..b5c97f1930
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
@@ -0,0 +1,52 @@
+## @file
+# SMM Library instance of Spi Flash Common Library Class
+#
+# Copyright (c) 2017 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
+ MinPlatformPkg/MinPlatformPkg.dec
+
+
+[Pcd]
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.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..11c832e487
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Component description file for the PchSpiCommonLib
+#
+# Copyright (c) 2017 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+
+[LibraryClasses]
+ IoLib
+ DebugLib
+
+[Pcd]
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
diff --git a/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc b/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
new file mode 100644
index 0000000000..a2d006ee35
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
@@ -0,0 +1,12 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE libraries.
+#
+# Copyright (c) 2017 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/PchPostMemoryInclude.fdf b/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
new file mode 100644
index 0000000000..78eca21a43
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf b/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
new file mode 100644
index 0000000000..2d3a127c20
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf b/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
new file mode 100644
index 0000000000..d079c593d9
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
@@ -0,0 +1,13 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 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/SmmControl/RuntimeDxe/SmmControl2Dxe.inf b/Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
new file mode 100644
index 0000000000..e23dd9f2fe
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
@@ -0,0 +1,59 @@
+## @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.
+#
+# 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..f7fdd3abbe
--- /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) 2017 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..265af00ac0
--- /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) 2017 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] 37+ messages in thread
* Re: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
2019-08-09 22:46 ` [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
@ 2019-08-15 8:34 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
1 sibling, 0 replies; 37+ messages in thread
From: Nate DeSimone @ 2019-08-15 8:34 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
Hi David,
Here are my comments:
1. All of the copyright years need to be updated to 2019.
2. Please remove " Contributed-under: TianoCore Contribution Agreement 1.0" from your commit message as it is no longer needed.
3. Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c - Please fix all the interspersed trailing white-space.
4. Silicon/Intel/SimicsX58SktPkg/SktPei.dsc - line 2 reads like this "Component description file for the SkyLake SiPkg PEI drivers.". This is Simics, not Sky Lake, please update the comment.
5. Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf - lines 10 & 11 - please remove the commented out code.
Other than that, looks good! Please send an updated patch.
Thanks,
Nate
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 9, 2019 3:47 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-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../Override/UefiCpuPkg/SecCore/SecMain.c | 956 +++++++++++++++++++++
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c | 148 ++++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c | 353 ++++++++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.c | 199 +++++
.../Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm | 45 +
.../Override/UefiCpuPkg/SecCore/SecMain.inf | 71 ++
.../Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm | 45 +
Silicon/Intel/SimicsX58SktPkg/SktPei.dsc | 18 +
.../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf | 9 +
.../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf | 10 +
Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf | 17 +
.../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf | 16 +
.../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf | 52 ++
.../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf | 64 ++
.../SimicsX58SktPkg/Smm/Access/SmramInternal.h | 81 ++
15 files changed, 2084 insertions(+)
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.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 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
create mode 100644 Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm
create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPei.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/Override/UefiCpuPkg/SecCore/SecMain.c b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
new file mode 100644
index 0000000000..c52d459ef2
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/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 <IndustryStandard/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_INFO, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32 (PcdSimicsDxeMemFvBase)));
+ DEBUG ((EFI_D_INFO, "OutputBuffer: 0x%x\n", OutputBuffer));
+ DEBUG ((EFI_D_INFO, "OutputBufferSize: 0x%x\n", OutputBufferSize));
+ DEBUG ((EFI_D_INFO, "ScratchBuffer: 0x%x\n", ScratchBuffer));
+ DEBUG ((EFI_D_INFO, "ScratchBufferSize: 0x%x\n", ScratchBufferSize));
+ DEBUG ((EFI_D_INFO, "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_ERROR, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "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/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..d07d88142a
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
@@ -0,0 +1,353 @@
+/** @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, 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 <SimicsPlatforms.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 QEMU 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 QEMU.
+ //
+
+ TopOfLowRam = GetSystemMemorySizeBelow4gb ();
+ ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) == 0);
+ TopOfLowRamMb = TopOfLowRam >> 20;
+ DEBUG((EFI_D_ERROR, "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_ERROR, "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_ERROR, "MCH_TSEGMB =0x%x; \n", PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
+ DEBUG((EFI_D_ERROR, "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..898fc25084
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
@@ -0,0 +1,199 @@
+/** @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 <Guid/AcpiS3Context.h>
+#include <IndustryStandard/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/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm
new file mode 100644
index 0000000000..19ffb6f86d
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm
@@ -0,0 +1,45 @@
+; @file
+; Copyright (c) 2006 - 2013 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/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
new file mode 100644
index 0000000000..ac993ac1ce
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
@@ -0,0 +1,71 @@
+## @file
+# SEC Driver
+#
+# Copyright (c) 2008 - 2018 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ BaseMemoryLib
+ PeiServicesLib
+ PcdLib
+ UefiCpuLib
+ DebugAgentLib
+ IoLib
+ PeCoffLib
+ PeCoffGetEntryPointLib
+ PeCoffExtraActionLib
+ ExtractGuidedSectionLib
+ LocalApicLib
+ PciCf8Lib
+
+[Ppis]
+ gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
+ gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+ gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+
+[FeaturePcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
diff --git a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm
new file mode 100644
index 0000000000..0eb86ec2ca
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm
@@ -0,0 +1,45 @@
+; @file
+; Copyright (c) 2006 - 2013 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/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
new file mode 100644
index 0000000000..0be8be4966
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
@@ -0,0 +1,18 @@
+## @file
+# Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+ #
+ # SEC Phase modules
+ #
+ $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf {
+ <LibraryClasses>
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ }
+ 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..78eca21a43
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 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..9f037e99d4
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
@@ -0,0 +1,10 @@
+## @file
+# Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 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..596d633cd3
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
@@ -0,0 +1,17 @@
+## @file
+# Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 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_SECMAIN USE = IA32 $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf
+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..9004b9cb83
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
@@ -0,0 +1,16 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+#INF $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuArchDxe/CpuArchDxe.inf
+#INF $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuMpDxe/CpuMpDxe.inf
+!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..2f630b4b95
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
@@ -0,0 +1,52 @@
+## @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.
+#
+# 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..1d3b028c85
--- /dev/null
+++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
@@ -0,0 +1,64 @@
+## @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.
+#
+# 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+ OvmfPkg/OvmfPkg.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] 37+ messages in thread
* Re: [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10
2019-08-09 22:46 ` [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10 David Wei
2019-08-13 2:01 ` Nate DeSimone
@ 2019-08-15 8:39 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2 siblings, 0 replies; 37+ messages in thread
From: Nate DeSimone @ 2019-08-15 8:39 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
Hi David,
Here are my comments:
1. All of the copyright years need to be updated to 2019.
2. Please remove " Contributed-under: TianoCore Contribution Agreement 1.0" from your commit message as it is no longer needed.
3. Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpi.c - I am surprised to see the DisableBiosWriteProtect() and EnableBiosWriteProtect() functions empty. Does Simics not emulate the EISS and BC registers?
4. Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpiSmm.inf - line 43 - Remove trailing whitespace
Other than that, looks good! Please send an updated patch.
Thanks,
Nate
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 9, 2019 3:47 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-platform patch 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>
Contributed-under: TianoCore Contribution Agreement 1.0
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 | 22 +
.../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 +++++++
.../IncludePrivate/Library/PchSpiCommonLib.h | 396 +++++++++
.../Library/ResetSystemLib/ResetSystemLib.inf | 34 +
.../SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf | 52 ++
.../BasePchSpiCommonLib/BasePchSpiCommonLib.inf | 33 +
Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc | 12 +
.../Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf | 9 +
.../Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf | 9 +
.../Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf | 13 +
.../SmmControl/RuntimeDxe/SmmControl2Dxe.inf | 59 ++
Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpi.h | 23 +
Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpiSmm.inf | 44 +
25 files changed, 4152 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/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/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/PchCommonLib.dsc
create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
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..46355e191c
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,137 @@
+/** @file
+ Reset System Library functions for OVMF
+
+ Copyright (c) 2006 - 2016 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 <IndustryStandard/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..3d4e24eac6
--- /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) 2017 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..1e5cd0d744
--- /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) 2017 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..77fb76d7cd
--- /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) 2017 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 <IndustryStandard/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..8fb4947b1a
--- /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 - 2010, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <IndustryStandard/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..19eb469657
--- /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) 2017 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..f9d340d6df
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/ICH10Pkg.dec
@@ -0,0 +1,22 @@
+## @file
+# Copyright (c) 2014 - 2016 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}}
diff --git a/Silicon/Intel/SimicsICH10Pkg/Include/Library/SpiFlashCommonLib.h b/Silicon/Intel/SimicsICH10Pkg/Include/Library/SpiFlashCommonLib.h
new file mode 100644
index 0000000000..c36360bcb0
--- /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) 2017 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..552ce28d8c
--- /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) 2017 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..d503d130c8
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/Include/PchLimits.h
@@ -0,0 +1,94 @@
+/** @file
+ Build time limits of PCH resources.
+
+ Copyright (c) 2017 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..00139fc230
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/Include/PchReservedResources.h
@@ -0,0 +1,60 @@
+/** @file
+ PCH preserved MMIO resource definitions.
+
+ Copyright (c) 2017 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..cb5f26c47b
--- /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) 2017 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..e08721f405
--- /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) 2017 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..a727aae927
--- /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) 2017 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/IncludePrivate/Library/PchSpiCommonLib.h b/Silicon/Intel/SimicsICH10Pkg/IncludePrivate/Library/PchSpiCommonLib.h
new file mode 100644
index 0000000000..5bdec96197
--- /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) 2017 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..4af462da47
--- /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 - 2018 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..b5c97f1930
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf
@@ -0,0 +1,52 @@
+## @file
+# SMM Library instance of Spi Flash Common Library Class
+#
+# Copyright (c) 2017 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
+ MinPlatformPkg/MinPlatformPkg.dec
+
+
+[Pcd]
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.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..11c832e487
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Component description file for the PchSpiCommonLib
+#
+# Copyright (c) 2017 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+
+[LibraryClasses]
+ IoLib
+ DebugLib
+
+[Pcd]
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
+ gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
diff --git a/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc b/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
new file mode 100644
index 0000000000..a2d006ee35
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
@@ -0,0 +1,12 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE libraries.
+#
+# Copyright (c) 2017 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/PchPostMemoryInclude.fdf b/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
new file mode 100644
index 0000000000..78eca21a43
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf b/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
new file mode 100644
index 0000000000..2d3a127c20
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
@@ -0,0 +1,9 @@
+## @file
+# Component description file for the SkyLake SiPkg PEI drivers.
+#
+# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
diff --git a/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf b/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
new file mode 100644
index 0000000000..d079c593d9
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
@@ -0,0 +1,13 @@
+## @file
+# Component description file for the SkyLake SiPkg DXE drivers.
+#
+# Copyright (c) 2017 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/SmmControl/RuntimeDxe/SmmControl2Dxe.inf b/Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
new file mode 100644
index 0000000000..e23dd9f2fe
--- /dev/null
+++ b/Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
@@ -0,0 +1,59 @@
+## @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.
+#
+# 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
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..f7fdd3abbe
--- /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) 2017 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..265af00ac0
--- /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) 2017 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] 37+ messages in thread
* Re: [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
2019-08-09 22:46 ` [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules David Wei
@ 2019-08-15 18:35 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
1 sibling, 0 replies; 37+ messages in thread
From: Nate DeSimone @ 2019-08-15 18:35 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
Hi David,
Here are my comments:
1. All of the copyright years need to be updated to 2019.
2. Please remove " Contributed-under: TianoCore Contribution Agreement 1.0" from your commit message as it is no longer needed.
3. Please remove interspersed trailing white-space from the following files:
* Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl
* Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
* Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h
* Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
* Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
4. Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c - Line 2 - " This driver effectuates OVMF's platform..." - This is not OVMF, this is Simics, please update.
5. Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf - Line 2 - " This driver installs SMBIOS information for OVMF" - This is not OVMF, this is Simics, please update.
Other than that, looks good! Please send an updated patch.
Thanks,
Nate
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 9, 2019 3:47 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-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
Add modules AcpiTables, Include, Library, PlatformDxe, PlatformPei, Policy, SmbiosPlatformDxe
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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../Library/LoadLinuxLib/Linux.c | 662 ++++++++++++++++
.../Library/LoadLinuxLib/LinuxGdt.c | 175 +++++
.../Library/NvVarsFileLib/FsAccess.c | 507 ++++++++++++
.../Library/NvVarsFileLib/NvVarsFileLib.c | 77 ++
.../SerializeVariablesLib/SerializeVariablesLib.c | 869 +++++++++++++++++++++
.../SimicsOpenBoardPkg/PlatformDxe/Platform.c | 865 ++++++++++++++++++++
.../PlatformDxe/PlatformConfig.c | 123 +++
.../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c | 57 ++
.../PlatformPei/FeatureControl.c | 114 +++
Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c | 100 +++
.../SimicsOpenBoardPkg/PlatformPei/MemDetect.c | 568 ++++++++++++++
.../SimicsOpenBoardPkg/PlatformPei/Platform.c | 631 +++++++++++++++
.../SiliconPolicyInitLib/SiliconPolicyInitLib.c | 108 +++
.../SiliconPolicyUpdateLib.c | 70 ++
.../SmbiosPlatformDxe/SmbiosPlatformDxe.c | 148 ++++
.../SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf | 31 +
.../Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl | 821 +++++++++++++++++++
.../Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h | 75 ++
.../Include/Guid/SimicsX58PlatformConfig.h | 17 +
.../Include/IndustryStandard/X58Ich10.h | 106 +++
.../SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h | 298 +++++++
.../SimicsOpenBoardPkg/Include/Protocol/IsaIo.h | 356 +++++++++
.../Include/Protocol/Legacy8259.h | 291 +++++++
.../Include/Register/X58SmramSaveStateMap.h | 178 +++++
.../SimicsOpenBoardPkg/Include/SimicsPlatforms.h | 54 ++
.../Library/LoadLinuxLib/Ia32/JumpToKernel.nasm | 41 +
.../Library/LoadLinuxLib/LoadLinuxLib.h | 52 ++
.../Library/LoadLinuxLib/LoadLinuxLib.inf | 42 +
.../Library/LoadLinuxLib/X64/JumpToKernel.nasm | 85 ++
.../Library/NvVarsFileLib/NvVarsFileLib.h | 55 ++
.../Library/NvVarsFileLib/NvVarsFileLib.inf | 53 ++
.../SerializeVariablesLib/SerializeVariablesLib.h | 33 +
.../SerializeVariablesLib.inf | 36 +
.../SimicsOpenBoardPkg/PlatformDxe/Platform.h | 37 +
.../SimicsOpenBoardPkg/PlatformDxe/Platform.inf | 65 ++
.../SimicsOpenBoardPkg/PlatformDxe/Platform.uni | 31 +
.../PlatformDxe/PlatformConfig.h | 51 ++
.../PlatformDxe/PlatformForms.vfr | 67 ++
.../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h | 50 ++
.../SimicsOpenBoardPkg/PlatformPei/Platform.h | 93 +++
.../SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf | 109 +++
.../SiliconPolicyInitLib/SiliconPolicyInitLib.inf | 38 +
.../SiliconPolicyUpdateLib.inf | 35 +
.../SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec | 168 ++++
.../SmbiosPlatformDxe/SmbiosPlatformDxe.h | 38 +
.../SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 51 ++
46 files changed, 8531 insertions(+)
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/SerializeVariablesLib/SerializeVariablesLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.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/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/SimicsX58PlatformConfig.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
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/LoadLinuxLib.inf
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/SerializeVariablesLib/SerializeVariablesLib.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.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/SimicsOpenBoardPkg.dec
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/LoadLinuxLib/Linux.c b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
new file mode 100644
index 0000000000..43a2dee9f6
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
@@ -0,0 +1,662 @@
+/** @file
+ Copyright (c) 2011 - 2014 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..624fbc37cb
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
@@ -0,0 +1,175 @@
+/** @file
+ Initialize GDT for Linux.
+
+ Copyright (c) 2006 - 2012 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..6ba8784cf3
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
@@ -0,0 +1,507 @@
+/** @file
+ File System Access for NvVarsFileLib
+
+ Copyright (c) 2004 - 2014 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..f60fbc6112
--- /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) 2009 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/SerializeVariablesLib/SerializeVariablesLib.c b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
new file mode 100644
index 0000000000..c32a978550
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.c
@@ -0,0 +1,869 @@
+/** @file
+ Serialize Variables Library implementation
+
+ Copyright (c) 2004 - 2011 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/PlatformDxe/Platform.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
new file mode 100644
index 0000000000..7bede1496d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
@@ -0,0 +1,865 @@
+/** @file
+ This driver effectuates OVMF's 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/SimicsX58PlatformConfig.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 PlatformDxeStrings[];
+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, &gSimicsX58PlatformConfigGuid,
+ 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
+ PlatformDxeStrings, // 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/PlatformDxe/PlatformConfig.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
new file mode 100644
index 0000000000..b3b2b34064
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
@@ -0,0 +1,123 @@
+/** @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
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Guid/SimicsX58PlatformConfig.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, &gSimicsX58PlatformConfigGuid,
+ 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, &gSimicsX58PlatformConfigGuid, &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/PlatformPei/Cmos.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
new file mode 100644
index 0000000000..fa2c22116c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
@@ -0,0 +1,57 @@
+/** @file
+ PC/AT CMOS access routines
+
+ Copyright (c) 2006 - 2009 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/PlatformPei/FeatureControl.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
new file mode 100644
index 0000000000..692405e417
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/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/PlatformPei/Fv.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
new file mode 100644
index 0000000000..818d135c95
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
@@ -0,0 +1,100 @@
+/** @file
+ Build FV related hobs for platform.
+
+ Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "PiPei.h"
+#include "Platform.h"
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+
+
+/**
+ 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/PlatformPei/MemDetect.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
new file mode 100644
index 0000000000..4c527baef2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
@@ -0,0 +1,568 @@
+/** @file
+ Memory Detection for Virtual Machines.
+
+ Copyright (c) 2006 - 2016 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/PlatformPei/Platform.c b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
new file mode 100644
index 0000000000..e64bdc7c56
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
@@ -0,0 +1,631 @@
+/** @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 ();
+ }
+ PeiFvInitialization ();
+ MemMapInitialization ();
+ }
+
+ MiscInitialization ();
+ InstallFeatureControlCallback ();
+
+ return EFI_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..01a9ed40d5
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.c
@@ -0,0 +1,108 @@
+/** @file
+ Copyright (c) 2018 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..6d9da67975
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.c
@@ -0,0 +1,70 @@
+/** @file
+ Copyright (c) 2018 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/SmbiosPlatformDxe/SmbiosPlatformDxe.c b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
new file mode 100644
index 0000000000..82a2d60959
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c
@@ -0,0 +1,148 @@
+/** @file
+ This driver installs SMBIOS information for OVMF
+
+ 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 OVMF
+
+ @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..839626eb86
--- /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 - 2018 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..76a8fbc081
--- /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) 2008 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF ", 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..6395ec11e2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
@@ -0,0 +1,75 @@
+/** @file
+ Platform specific defines for constructing ACPI tables
+
+ Copyright (c) 2013 - 2008 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef _Platform_h_INCLUDED_
+#define _Platform_h_INCLUDED_
+
+#include <PiDxe.h>
+#include <IndustryStandard/Acpi.h>
+
+//
+// ACPI table information used to initialize tables.
+//
+#define EFI_ACPI_OEM_ID 'O','V','M','F',' ',' ' // OEMID 6 bytes long
+#define EFI_ACPI_OEM_TABLE_ID SIGNATURE_64('O','V','M','F','E','D','K','2') // OEM table id 8 bytes long
+#define EFI_ACPI_OEM_REVISION 0x02000820
+#define EFI_ACPI_CREATOR_ID SIGNATURE_32('O','V','M','F')
+#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/SimicsX58PlatformConfig.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.h
new file mode 100644
index 0000000000..f65f61d74d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.h
@@ -0,0 +1,17 @@
+/** @file
+ GUID for UEFI variables that are specific to OVMF configuration.
+
+ Copyright (C) 2014, Red Hat, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __SIMICSX58_PLATFORM_CONFIG_H__
+#define __SIMICSX58_PLATFORM_CONFIG_H__
+
+#define SIMICSX58_PLATFORM_CONFIG_GUID \
+{0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
+
+extern EFI_GUID gSimicsX58PlatformConfigGuid;
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
new file mode 100644
index 0000000000..36c08176d1
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
@@ -0,0 +1,106 @@
+/** @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>
+
+//
+// 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/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
new file mode 100644
index 0000000000..12aeb1227c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
@@ -0,0 +1,298 @@
+/** @file
+ EFI ISA ACPI Protocol is used to enumerate and manage all the ISA controllers on
+ the platform's ISA Bus.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __ISA_ACPI_H_
+#define __ISA_ACPI_H_
+
+///
+/// Global ID for the EFI ISA ACPI Protocol.
+///
+#define EFI_ISA_ACPI_PROTOCOL_GUID \
+ { \
+ 0x64a892dc, 0x5561, 0x4536, { 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55 } \
+ }
+
+///
+/// Forward declaration fo the EFI ISA ACPI Protocol
+///
+typedef struct _EFI_ISA_ACPI_PROTOCOL EFI_ISA_ACPI_PROTOCOL;
+
+///
+/// ISA ACPI Protocol interrupt resource attributes.
+///
+#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_EDGE_SENSITIVE 0x01 ///< Edge triggered interrupt on a rising edge.
+#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_EDGE_SENSITIVE 0x02 ///< Edge triggered interrupt on a falling edge.
+#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_LEVEL_SENSITIVE 0x04 ///< Level sensitive interrupt active high.
+#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_LEVEL_SENSITIVE 0x08 ///< Level sensitive interrupt active low.
+
+///
+/// ISA ACPI Protocol DMA resource attributes.
+///
+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_MASK 0x03 ///< Bit mask of supported DMA speed attributes.
+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_COMPATIBILITY 0x00 ///< ISA controller supports compatibility mode DMA transfers.
+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_A 0x01 ///< ISA controller supports type A DMA transfers.
+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_B 0x02 ///< ISA controller supports type B DMA transfers.
+#define EFI_ISA_ACPI_DMA_SPEED_TYPE_F 0x03 ///< ISA controller supports type F DMA transfers.
+#define EFI_ISA_ACPI_DMA_COUNT_BY_BYTE 0x04 ///< ISA controller increments DMA address by bytes (8-bit).
+#define EFI_ISA_ACPI_DMA_COUNT_BY_WORD 0x08 ///< ISA controller increments DMA address by words (16-bit).
+#define EFI_ISA_ACPI_DMA_BUS_MASTER 0x10 ///< ISA controller is a DMA bus master.
+#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT 0x20 ///< ISA controller only supports 8-bit DMA transfers.
+#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT_AND_16_BIT 0x40 ///< ISA controller both 8-bit and 16-bit DMA transfers.
+#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_16_BIT 0x80 ///< ISA controller only supports 16-bit DMA transfers.
+
+///
+/// ISA ACPI Protocol MMIO resource attributes
+///
+#define EFI_ISA_ACPI_MEMORY_WIDTH_MASK 0x03 ///< Bit mask of supported ISA memory width attributes.
+#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT 0x00 ///< ISA MMIO region only supports 8-bit access.
+#define EFI_ISA_ACPI_MEMORY_WIDTH_16_BIT 0x01 ///< ISA MMIO region only supports 16-bit access.
+#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT_AND_16_BIT 0x02 ///< ISA MMIO region supports both 8-bit and 16-bit access.
+#define EFI_ISA_ACPI_MEMORY_WRITEABLE 0x04 ///< ISA MMIO region supports write transactions.
+#define EFI_ISA_ACPI_MEMORY_CACHEABLE 0x08 ///< ISA MMIO region supports being cached.
+#define EFI_ISA_ACPI_MEMORY_SHADOWABLE 0x10 ///< ISA MMIO region may be shadowed.
+#define EFI_ISA_ACPI_MEMORY_EXPANSION_ROM 0x20 ///< ISA MMIO region is an expansion ROM.
+
+///
+/// ISA ACPI Protocol I/O resource attributes
+///
+#define EFI_ISA_ACPI_IO_DECODE_10_BITS 0x01 ///< ISA controllers uses a 10-bit address decoder for I/O cycles.
+#define EFI_ISA_ACPI_IO_DECODE_16_BITS 0x02 ///< ISA controllers uses a 16-bit address decoder for I/O cycles.
+
+///
+/// EFI ISA ACPI resource type
+///
+typedef enum {
+ EfiIsaAcpiResourceEndOfList, ///< Marks the end if a resource list.
+ EfiIsaAcpiResourceIo, ///< ISA I/O port resource range.
+ EfiIsaAcpiResourceMemory, ///< ISA MMIO resource range.
+ EfiIsaAcpiResourceDma, ///< ISA DMA resource.
+ EfiIsaAcpiResourceInterrupt ///< ISA interrupt resource.
+} EFI_ISA_ACPI_RESOURCE_TYPE;
+
+///
+/// EFI ISA ACPI generic resource structure
+///
+typedef struct {
+ EFI_ISA_ACPI_RESOURCE_TYPE Type; ///< The type of resource (I/O, MMIO, DMA, Interrupt).
+ UINT32 Attribute; ///< Bit mask of attributes associated with this resource. See EFI_ISA_ACPI_xxx macros for valid combinations.
+ UINT32 StartRange; ///< The start of the resource range.
+ UINT32 EndRange; ///< The end of the resource range.
+} EFI_ISA_ACPI_RESOURCE;
+
+///
+/// EFI ISA ACPI resource device identifier
+///
+typedef struct {
+ UINT32 HID; ///< The ACPI Hardware Identifier value associated with an ISA controller. Matchs ACPI DSDT contents.
+ UINT32 UID; ///< The ACPI Unique Identifier value associated with an ISA controller. Matches ACPI DSDT contents.
+} EFI_ISA_ACPI_DEVICE_ID;
+
+///
+/// EFI ISA ACPI resource list
+///
+typedef struct {
+ EFI_ISA_ACPI_DEVICE_ID Device; ///< The ACPI HID/UID associated with an ISA controller.
+ EFI_ISA_ACPI_RESOURCE *ResourceItem; ///< A pointer to the list of resources associated with an ISA controller.
+} EFI_ISA_ACPI_RESOURCE_LIST;
+
+/**
+ Enumerates the ISA controllers on an ISA bus.
+
+ This service allows all the ISA controllers on an ISA bus to be enumerated. If
+ Device is a pointer to a NULL value, then the first ISA controller on the ISA
+ bus is returned in Device and EFI_SUCCESS is returned. If Device is a pointer
+ to a value that was returned on a prior call to DeviceEnumerate(), then the next
+ ISA controller on the ISA bus is returned in Device and EFI_SUCCESS is returned.
+ If Device is a pointer to the last ISA controller on the ISA bus, then
+ EFI_NOT_FOUND is returned.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[out] Device The pointer to an ISA controller named by ACPI HID/UID.
+
+ @retval EFI_SUCCESS The next ISA controller on the ISA bus was returned.
+ @retval EFI_NOT_FOUND No device found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_DEVICE_ENUMERATE)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ OUT EFI_ISA_ACPI_DEVICE_ID **Device
+ );
+
+/**
+ Sets the power state of an ISA controller.
+
+ This services sets the power state of the ISA controller specified by Device to
+ the power state specified by OnOff. TRUE denotes on, FALSE denotes off.
+ If the power state is sucessfully set on the ISA Controller, then
+ EFI_SUCCESS is returned.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
+ @param[in] OnOff TRUE denotes on, FALSE denotes off.
+
+ @retval EFI_SUCCESS Successfully set the power state of the ISA controller.
+ @retval Other The ISA controller could not be placed in the requested power state.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_SET_DEVICE_POWER)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ IN EFI_ISA_ACPI_DEVICE_ID *Device,
+ IN BOOLEAN OnOff
+ );
+
+/**
+ Retrieves the current set of resources associated with an ISA controller.
+
+ Retrieves the set of I/O, MMIO, DMA, and interrupt resources currently
+ assigned to the ISA controller specified by Device. These resources
+ are returned in ResourceList.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
+ @param[out] ResourceList The pointer to the current resource list for Device.
+
+ @retval EFI_SUCCESS Successfully retrieved the current resource list.
+ @retval EFI_NOT_FOUND The resource list could not be retrieved.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_GET_CUR_RESOURCE)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ IN EFI_ISA_ACPI_DEVICE_ID *Device,
+ OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
+ );
+
+/**
+ Retrieves the set of possible resources that may be assigned to an ISA controller
+ with SetResource().
+
+ Retrieves the possible sets of I/O, MMIO, DMA, and interrupt resources for the
+ ISA controller specified by Device. The sets are returned in ResourceList.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
+ @param[out] ResourceList The pointer to the returned list of resource lists.
+
+ @retval EFI_UNSUPPORTED This service is not supported.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_GET_POS_RESOURCE)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ IN EFI_ISA_ACPI_DEVICE_ID *Device,
+ OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
+ );
+
+/**
+ Assigns resources to an ISA controller.
+
+ Assigns the I/O, MMIO, DMA, and interrupt resources specified by ResourceList
+ to the ISA controller specified by Device. ResourceList must match a resource list returned by GetPosResource() for the same ISA controller.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
+ @param[in] ResourceList The pointer to a resources list that must be one of the
+ resource lists returned by GetPosResource() for the
+ ISA controller specified by Device.
+
+ @retval EFI_SUCCESS Successfully set resources on the ISA controller.
+ @retval Other The resources could not be set for the ISA controller.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_SET_RESOURCE)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ IN EFI_ISA_ACPI_DEVICE_ID *Device,
+ IN EFI_ISA_ACPI_RESOURCE_LIST *ResourceList
+ );
+
+/**
+ Enables or disables an ISA controller.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[in] Device The pointer to the ISA controller to enable/disable.
+ @param[in] Enable TRUE to enable the ISA controller. FALSE to disable the
+ ISA controller.
+
+ @retval EFI_SUCCESS Successfully enabled/disabled the ISA controller.
+ @retval Other The ISA controller could not be placed in the requested state.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_ENABLE_DEVICE)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ IN EFI_ISA_ACPI_DEVICE_ID *Device,
+ IN BOOLEAN Enable
+ );
+
+/**
+ Initializes an ISA controller, so that it can be used. This service must be called
+ before SetResource(), EnableDevice(), or SetPower() will behave as expected.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+ @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
+
+ @retval EFI_SUCCESS Successfully initialized an ISA controller.
+ @retval Other The ISA controller could not be initialized.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_INIT_DEVICE)(
+ IN EFI_ISA_ACPI_PROTOCOL *This,
+ IN EFI_ISA_ACPI_DEVICE_ID *Device
+ );
+
+/**
+ Initializes all the HW states required for the ISA controllers on the ISA bus
+ to be enumerated and managed by the rest of the services in this prorotol.
+ This service must be called before any of the other services in this
+ protocol will function as expected.
+
+ @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
+
+ @retval EFI_SUCCESS Successfully initialized all required hardware states.
+ @retval Other The ISA interface could not be initialized.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_ACPI_INTERFACE_INIT)(
+ IN EFI_ISA_ACPI_PROTOCOL *This
+ );
+
+///
+/// The EFI_ISA_ACPI_PROTOCOL provides the services to enumerate and manage
+/// ISA controllers on an ISA bus. These services include the ability to initialize,
+/// enable, disable, and manage the power state of ISA controllers. It also
+/// includes services to query current resources, query possible resources,
+/// and assign resources to an ISA controller.
+///
+struct _EFI_ISA_ACPI_PROTOCOL {
+ EFI_ISA_ACPI_DEVICE_ENUMERATE DeviceEnumerate;
+ EFI_ISA_ACPI_SET_DEVICE_POWER SetPower;
+ EFI_ISA_ACPI_GET_CUR_RESOURCE GetCurResource;
+ EFI_ISA_ACPI_GET_POS_RESOURCE GetPosResource;
+ EFI_ISA_ACPI_SET_RESOURCE SetResource;
+ EFI_ISA_ACPI_ENABLE_DEVICE EnableDevice;
+ EFI_ISA_ACPI_INIT_DEVICE InitDevice;
+ EFI_ISA_ACPI_INTERFACE_INIT InterfaceInit;
+};
+
+extern EFI_GUID gEfiIsaAcpiProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
new file mode 100644
index 0000000000..30000305fb
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
@@ -0,0 +1,356 @@
+/** @file
+ ISA I/O Protocol is used by ISA device drivers to perform I/O, MMIO and DMA
+ operations on the ISA controllers they manage.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_ISA_IO_H_
+#define _EFI_ISA_IO_H_
+
+#include <Protocol/IsaAcpi.h>
+
+///
+/// Global ID for the EFI_ISA_IO_PROTOCOL
+///
+#define EFI_ISA_IO_PROTOCOL_GUID \
+ { \
+ 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+///
+/// Forward declaration for the EFI_ISA_IO_PROTOCOL.
+///
+typedef struct _EFI_ISA_IO_PROTOCOL EFI_ISA_IO_PROTOCOL;
+
+///
+/// Width of EFI_ISA_IO_PROTOCOL I/O Port and MMIO operations.
+///
+typedef enum {
+ EfiIsaIoWidthUint8 = 0, ///< 8-bit operation.
+ EfiIsaIoWidthUint16, ///< 16-bit operation.
+ EfiIsaIoWidthUint32, ///< 32-bit operation
+ EfiIsaIoWidthReserved,
+ EfiIsaIoWidthFifoUint8, ///< 8-bit FIFO operation.
+ EfiIsaIoWidthFifoUint16, ///< 16-bit FIFO operation.
+ EfiIsaIoWidthFifoUint32, ///< 32-bit FIFO operation.
+ EfiIsaIoWidthFifoReserved,
+ EfiIsaIoWidthFillUint8, ///< 8-bit Fill operation.
+ EfiIsaIoWidthFillUint16, ///< 16-bit Fill operation.
+ EfiIsaIoWidthFillUint32, ///< 32-bit Fill operation.
+ EfiIsaIoWidthFillReserved,
+ EfiIsaIoWidthMaximum
+} EFI_ISA_IO_PROTOCOL_WIDTH;
+
+///
+/// Attributes for the EFI_ISA_IO_PROTOCOL common DMA buffer allocations.
+///
+#define EFI_ISA_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x080 ///< Map a memory range so write are combined.
+#define EFI_ISA_IO_ATTRIBUTE_MEMORY_CACHED 0x800 ///< Map a memory range so all read and write accesses are cached.
+#define EFI_ISA_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000 ///< Disable a memory range.
+
+///
+/// Channel attribute for EFI_ISA_IO_PROTOCOL slave DMA requests
+///
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE 0x001 ///< Set the speed of the DMA transfer in compatible mode.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_A 0x002 ///< Not supported.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_B 0x004 ///< Not supported.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_C 0x008 ///< Not supported.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8 0x010 ///< Request 8-bit DMA transfers. Only available on channels 0..3.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16 0x020 ///< Request 16-bit DMA transfers. Only available on channels 4..7.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE 0x040 ///< Request a single DMA transfer.
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE 0x080 ///< Request multiple DMA transfers until TC (Terminal Count) or EOP (End of Process).
+#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_AUTO_INITIALIZE 0x100 ///< Automatically reload base and count at the end of the DMA transfer.
+
+///
+/// The DMA opreration type for EFI_ISA_IO_PROTOCOL DMA requests.
+///
+typedef enum {
+ ///
+ /// A read operation from system memory by a bus master.
+ ///
+ EfiIsaIoOperationBusMasterRead,
+ ///
+ /// A write operation to system memory by a bus master.
+ ///
+ EfiIsaIoOperationBusMasterWrite,
+ ///
+ /// Provides both read and write access to system memory by both the processor
+ /// and a bus master. The buffer is coherent from both the processor's and the
+ /// bus master's point of view.
+ ///
+ EfiIsaIoOperationBusMasterCommonBuffer,
+ ///
+ /// A read operation from system memory by a slave device.
+ ///
+ EfiIsaIoOperationSlaveRead,
+ ///
+ /// A write operation to system memory by a slave master.
+ ///
+ EfiIsaIoOperationSlaveWrite,
+ EfiIsaIoOperationMaximum
+} EFI_ISA_IO_PROTOCOL_OPERATION;
+
+/**
+ Performs ISA I/O and MMIO Read/Write Cycles
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ @param[in] Width Specifies the width of the I/O or MMIO operation.
+ @param[in] Offset The offset into the ISA I/O or MMIO space to start the
+ operation.
+ @param[in] Count The number of I/O or MMIO operations to perform.
+ @param[in, out] Buffer For read operations, the destination buffer to store
+ the results. For write operations, the source buffer to
+ write data from.
+
+ @retval EFI_SUCCESS The data was successfully read from or written to the device.
+ @retval EFI_UNSUPPORTED The Offset is not valid for this device.
+ @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_IO_MEM)(
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+///
+/// Structure of functions for accessing ISA I/O and MMIO space.
+///
+typedef struct {
+ ///
+ /// Read from ISA I/O or MMIO space.
+ ///
+ EFI_ISA_IO_PROTOCOL_IO_MEM Read;
+ ///
+ /// Write to ISA I/O or MMIO space.
+ ///
+ EFI_ISA_IO_PROTOCOL_IO_MEM Write;
+} EFI_ISA_IO_PROTOCOL_ACCESS;
+
+/**
+ Copies data from one region of ISA MMIO space to another region of ISA
+ MMIO space.
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ @param[in] Width Specifies the width of the MMIO copy operation.
+ @param[in] DestOffset The offset of the destination in ISA MMIO space.
+ @param[in] SrcOffset The offset of the source in ISA MMIO space.
+ @param[in] Count The number tranfers to perform for this copy operation.
+
+ @retval EFI_SUCCESS The data was copied sucessfully.
+ @retval EFI_UNSUPPORTED The DestOffset or SrcOffset is not valid for this device.
+ @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_COPY_MEM)(
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 DestOffset,
+ IN UINT32 SrcOffset,
+ IN UINTN Count
+ );
+
+/**
+ Maps a memory region for DMA.
+
+ This function returns the device-specific addresses required to access system memory.
+ This function is used to map system memory for ISA DMA operations. All ISA DMA
+ operations must be performed through their mapped addresses, and such mappings must
+ be freed with EFI_ISA_IO_PROTOCOL.Unmap() after the DMA operation is completed.
+
+ If the DMA operation is a single read or write data transfer through an ISA bus
+ master, then EfiIsaIoOperationBusMasterRead or EfiIsaIoOperationBusMasterWrite
+ is used and the range is unmapped to complete the operation. If the DMA operation
+ is a single read or write data transfer through an ISA slave controller, then
+ EfiIsaIoOperationSlaveRead or EfiIsaIoOperationSlaveWrite is used and the range
+ is unmapped to complete the operation.
+
+ If performing a DMA read operation, all the data must be present in system memory before the Map() is performed. Similarly,
+ if performing a DMA write operation, the data must not be accessed in system
+ memory until EFI_ISA_IO_PROTOCOL.Unmap() is performed. Bus master operations that
+ require both read and write access or require multiple host device interactions
+ within the same mapped region must use EfiIsaIoOperationBusMasterCommonBuffer.
+ However, only memory allocated via the EFI_ISA_IO_PROTOCOL.AllocateBuffer() interface
+ is guaranteed to be able to be mapped for this operation type. In all mapping
+ requests the NumberOfBytes returned may be less than originally requested. It is
+ the caller's responsibility to make additional requests to complete the entire
+ transfer.
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ @param[in] Operation Indicates the type of DMA (slave or bus master),
+ and if the DMA operation is going to read or
+ write to system memory.
+ @param[in] ChannelNumber The slave channel number to use for this DMA
+ operation. If Operation and ChannelAttributes
+ shows that this device performs bus mastering
+ DMA, then this field is ignored. The legal
+ range for this field is 0..7.
+ @param[in] ChannelAttributes A bitmask of the attributes used to configure
+ the slave DMA channel for this DMA operation.
+ See EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_* for the
+ legal bit combinations.
+ @param[in] HostAddress The system memory address to map to the device.
+ @param[in, out] NumberOfBytes On input the number of bytes to map. On
+ output the number of bytes that were mapped.
+ @param[out] DeviceAddress The resulting map address for the bus master
+ device to use to access the hosts HostAddress.
+ @param[out] Mapping A returned value that must be passed to into
+ EFI_ISA_IO_PROTOCOL.Unmap() to free all the the
+ resources associated with this map request.
+
+ @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes.
+ @retval EFI_INVALID_PARAMETER The Operation is undefined.
+ @retval EFI_INVALID_PARAMETER The HostAddress is undefined.
+ @retval EFI_UNSUPPORTED The HostAddress can not be mapped as a common buffer.
+ @retval EFI_DEVICE_ERROR The system hardware could not map the requested address.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_MAP)(
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ISA_IO_PROTOCOL_OPERATION Operation,
+ IN UINT8 ChannelNumber OPTIONAL,
+ IN UINT32 ChannelAttributes,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ );
+
+/**
+ Unmaps a memory region that was previously mapped with EFI_ISA_IO_PROTOCOL.Map().
+
+ The EFI_ISA_IO_PROTOCOL.Map() operation is completed and any corresponding
+ resources are released. If the operation was EfiIsaIoOperationSlaveWrite
+ or EfiIsaIoOperationBusMasterWrite, the data is committed to system memory.
+ Any resources used for the mapping are freed.
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ @param[in] Mapping The mapping value returned from EFI_ISA_IO_PROTOCOL.Map().
+
+ @retval EFI_SUCCESS The memory region was unmapped.
+ @retval EFI_DEVICE_ERROR The data was not committed to the target system memory.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_UNMAP)(
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ );
+
+/**
+ Allocates pages that are suitable for an EfiIsaIoOperationBusMasterCommonBuffer
+ mapping.
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ @param[in] Type The type allocation to perform.
+ @param[in] MemoryType The type of memory to allocate.
+ @param[in] Pages The number of pages to allocate.
+ @param[out] HostAddress A pointer to store the base address of the allocated range.
+ @param[in] Attributes The requested bit mask of attributes for the allocated range.
+
+ @retval EFI_SUCCESS The requested memory pages were allocated.
+ @retval EFI_INVALID_PARAMETER Type is invalid.
+ @retval EFI_INVALID_PARAMETER MemoryType is invalid.
+ @retval EFI_INVALID_PARAMETER HostAddress is NULL.
+ @retval EFI_UNSUPPORTED Attributes is unsupported.
+ @retval EFI_UNSUPPORTED The memory range specified by HostAddress, Pages,
+ and Type is not available for common buffer use.
+ @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER)(
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ );
+
+/**
+ Frees a common buffer that was allocated with EFI_ISA_IO_PROTOCOL.AllocateBuffer().
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+ @param[in] Pages The number of pages to free from the previously allocated common buffer.
+ @param[in] HostAddress The base address of the previously allocated common buffer.
+
+
+ @retval EFI_SUCCESS The requested memory pages were freed.
+ @retval EFI_INVALID_PARAMETER The memory was not allocated with EFI_ISA_IO.AllocateBufer().
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_FREE_BUFFER)(
+ IN EFI_ISA_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ );
+
+/**
+ Flushes a DMA buffer, which forces all DMA posted write transactions to complete.
+
+ @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The DMA buffers were flushed.
+ @retval EFI_DEVICE_ERROR The buffers were not flushed due to a hardware error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ISA_IO_PROTOCOL_FLUSH)(
+ IN EFI_ISA_IO_PROTOCOL *This
+ );
+
+///
+/// The EFI_ISA_IO_PROTOCOL provides the basic Memory, I/O, and DMA interfaces
+/// used to abstract accesses to ISA controllers. There is one EFI_ISA_IO_PROTOCOL
+/// instance for each ISA controller on a ISA bus. A device driver that wishes
+/// to manage an ISA controller in a system will have to retrieve the
+/// ISA_PCI_IO_PROTOCOL instance associated with the ISA controller.
+///
+struct _EFI_ISA_IO_PROTOCOL {
+ EFI_ISA_IO_PROTOCOL_ACCESS Mem;
+ EFI_ISA_IO_PROTOCOL_ACCESS Io;
+ EFI_ISA_IO_PROTOCOL_COPY_MEM CopyMem;
+ EFI_ISA_IO_PROTOCOL_MAP Map;
+ EFI_ISA_IO_PROTOCOL_UNMAP Unmap;
+ EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer;
+ EFI_ISA_IO_PROTOCOL_FREE_BUFFER FreeBuffer;
+ EFI_ISA_IO_PROTOCOL_FLUSH Flush;
+ ///
+ /// The list of I/O , MMIO, DMA, and Interrupt resources associated with the
+ /// ISA controller abstracted by this instance of the EFI_ISA_IO_PROTOCOL.
+ ///
+ EFI_ISA_ACPI_RESOURCE_LIST *ResourceList;
+ ///
+ /// The size, in bytes, of the ROM image.
+ ///
+ UINT32 RomSize;
+ ///
+ /// A pointer to the in memory copy of the ROM image. The ISA Bus Driver is responsible
+ /// for allocating memory for the ROM image, and copying the contents of the ROM to memory
+ /// during ISA Bus initialization.
+ ///
+ VOID *RomImage;
+};
+
+extern EFI_GUID gEfiIsaIoProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
new file mode 100644
index 0000000000..c38f2feba7
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
@@ -0,0 +1,291 @@
+/** @file
+ This protocol abstracts the 8259 interrupt controller. This includes
+ PCI IRQ routing needed to program the PCI Interrupt Line register.
+
+ Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ This protocol is defined in Framework for EFI Compatibility Support Module spec
+ Version 0.97.
+
+**/
+
+#ifndef _EFI_LEGACY_8259_H_
+#define _EFI_LEGACY_8259_H_
+
+
+#define EFI_LEGACY_8259_PROTOCOL_GUID \
+ { \
+ 0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1 } \
+ }
+
+typedef struct _EFI_LEGACY_8259_PROTOCOL EFI_LEGACY_8259_PROTOCOL;
+
+typedef enum {
+ Efi8259Irq0,
+ Efi8259Irq1,
+ Efi8259Irq2,
+ Efi8259Irq3,
+ Efi8259Irq4,
+ Efi8259Irq5,
+ Efi8259Irq6,
+ Efi8259Irq7,
+ Efi8259Irq8,
+ Efi8259Irq9,
+ Efi8259Irq10,
+ Efi8259Irq11,
+ Efi8259Irq12,
+ Efi8259Irq13,
+ Efi8259Irq14,
+ Efi8259Irq15,
+ Efi8259IrqMax
+} EFI_8259_IRQ;
+
+typedef enum {
+ Efi8259LegacyMode,
+ Efi8259ProtectedMode,
+ Efi8259MaxMode
+} EFI_8259_MODE;
+
+/**
+ Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
+ the legacy mode mask and the protected mode mask. The base address for the 8259
+ is different for legacy and protected mode, so two masks are required.
+
+ @param This The protocol instance pointer.
+ @param MasterBase The base vector for the Master PIC in the 8259 controller.
+ @param SlaveBase The base vector for the Slave PIC in the 8259 controller.
+
+ @retval EFI_SUCCESS The new bases were programmed.
+ @retval EFI_DEVICE_ERROR A device error occured programming the vector bases.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_SET_VECTOR_BASE)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT8 MasterBase,
+ IN UINT8 SlaveBase
+ );
+
+/**
+ Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
+ the legacy mode mask and the protected mode mask. The base address for the 8259
+ is different for legacy and protected mode, so two masks are required.
+
+ @param This The protocol instance pointer.
+ @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15.
+ @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
+ @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15.
+ @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
+
+ @retval EFI_SUCCESS 8259 status returned.
+ @retval EFI_DEVICE_ERROR Error reading 8259.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_GET_MASK)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ OUT UINT16 *LegacyMask, OPTIONAL
+ OUT UINT16 *LegacyEdgeLevel, OPTIONAL
+ OUT UINT16 *ProtectedMask, OPTIONAL
+ OUT UINT16 *ProtectedEdgeLevel OPTIONAL
+ );
+
+/**
+ Set the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
+ the legacy mode mask and the protected mode mask. The base address for the 8259
+ is different for legacy and protected mode, so two masks are required.
+ Also set the edge/level masks.
+
+ @param This The protocol instance pointer.
+ @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15.
+ @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
+ @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15.
+ @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
+
+ @retval EFI_SUCCESS 8259 status returned.
+ @retval EFI_DEVICE_ERROR Error writing 8259.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_SET_MASK)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT16 *LegacyMask, OPTIONAL
+ IN UINT16 *LegacyEdgeLevel, OPTIONAL
+ IN UINT16 *ProtectedMask, OPTIONAL
+ IN UINT16 *ProtectedEdgeLevel OPTIONAL
+ );
+
+/**
+ Set the 8259 mode of operation. The base address for the 8259 is different for
+ legacy and protected mode. The legacy mode requires the master 8259 to have a
+ master base of 0x08 and the slave base of 0x70. The protected mode base locations
+ are not defined. Interrupts must be masked by the caller before this function
+ is called. The interrupt mask from the current mode is saved. The interrupt
+ mask for the new mode is Mask, or if Mask does not exist the previously saved
+ mask is used.
+
+ @param This The protocol instance pointer.
+ @param Mode The mode of operation. i.e. the real mode or protected mode.
+ @param Mask Optional interupt mask for the new mode.
+ @param EdgeLevel Optional trigger mask for the new mode.
+
+ @retval EFI_SUCCESS 8259 programmed.
+ @retval EFI_DEVICE_ERROR Error writing to 8259.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_SET_MODE)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_MODE Mode,
+ IN UINT16 *Mask, OPTIONAL
+ IN UINT16 *EdgeLevel OPTIONAL
+ );
+
+/**
+ Convert from IRQ to processor interrupt vector number.
+
+ @param This The protocol instance pointer.
+ @param Irq 8259 IRQ0 - IRQ15.
+ @param Vector The processor vector number that matches an Irq.
+
+ @retval EFI_SUCCESS The Vector matching Irq is returned.
+ @retval EFI_INVALID_PARAMETER The Irq not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_GET_VECTOR)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ OUT UINT8 *Vector
+ );
+
+/**
+ Enable Irq by unmasking interrupt in 8259
+
+ @param This The protocol instance pointer.
+ @param Irq 8259 IRQ0 - IRQ15.
+ @param LevelTriggered TRUE if level triggered. FALSE if edge triggered.
+
+ @retval EFI_SUCCESS The Irq was enabled on 8259.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_ENABLE_IRQ)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ IN BOOLEAN LevelTriggered
+ );
+
+/**
+ Disable Irq by masking interrupt in 8259
+
+ @param This The protocol instance pointer.
+ @param Irq 8259 IRQ0 - IRQ15.
+
+ @retval EFI_SUCCESS The Irq was disabled on 8259.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_DISABLE_IRQ)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ );
+
+/**
+ PciHandle represents a PCI config space of a PCI function. Vector
+ represents Interrupt Pin (from PCI config space) and it is the data
+ that is programmed into the Interrupt Line (from the PCI config space)
+ register.
+
+ @param This The protocol instance pointer.
+ @param PciHandle The PCI function to return the vector for.
+ @param Vector The vector for the function it matches.
+
+ @retval EFI_SUCCESS A valid Vector was returned.
+ @retval EFI_INVALID_PARAMETER PciHandle not valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_GET_INTERRUPT_LINE)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT UINT8 *Vector
+ );
+
+/**
+ Send an EOI to 8259
+
+ @param This The protocol instance pointer.
+ @param Irq 8259 IRQ0 - IRQ15.
+
+ @retval EFI_SUCCESS EOI was successfully sent to 8259.
+ @retval EFI_INVALID_PARAMETER The Irq isnot valid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_8259_END_OF_INTERRUPT)(
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ );
+
+/**
+ @par Protocol Description:
+ Abstracts the 8259 and APIC hardware control between EFI usage and
+ Compatibility16 usage.
+
+ @param SetVectorBase
+ Sets the vector bases for master and slave PICs.
+
+ @param GetMask
+ Gets IRQ and edge/level masks for 16-bit real mode and 32-bit protected mode.
+
+ @param SetMask
+ Sets the IRQ and edge\level masks for 16-bit real mode and 32-bit protected mode.
+
+ @param SetMode
+ Sets PIC mode to 16-bit real mode or 32-bit protected mode.
+
+ @param GetVector
+ Gets the base vector assigned to an IRQ.
+
+ @param EnableIrq
+ Enables an IRQ.
+
+ @param DisableIrq
+ Disables an IRQ.
+
+ @param GetInterruptLine
+ Gets an IRQ that is assigned to a PCI device.
+
+ @param EndOfInterrupt
+ Issues the end of interrupt command.
+
+**/
+struct _EFI_LEGACY_8259_PROTOCOL {
+ EFI_LEGACY_8259_SET_VECTOR_BASE SetVectorBase;
+ EFI_LEGACY_8259_GET_MASK GetMask;
+ EFI_LEGACY_8259_SET_MASK SetMask;
+ EFI_LEGACY_8259_SET_MODE SetMode;
+ EFI_LEGACY_8259_GET_VECTOR GetVector;
+ EFI_LEGACY_8259_ENABLE_IRQ EnableIrq;
+ EFI_LEGACY_8259_DISABLE_IRQ DisableIrq;
+ EFI_LEGACY_8259_GET_INTERRUPT_LINE GetInterruptLine;
+ EFI_LEGACY_8259_END_OF_INTERRUPT EndOfInterrupt;
+};
+
+extern EFI_GUID gEfiLegacy8259ProtocolGuid;
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap.h
new file mode 100644
index 0000000000..640ac4943d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/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/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
new file mode 100644
index 0000000000..c79111d811
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
@@ -0,0 +1,54 @@
+/** @file
+ OVMF Platform definitions
+
+ Copyright (C) 2015, Red Hat, Inc.
+ Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef __OVMF_PLATFORMS_H__
+#define __OVMF_PLATFORMS_H__
+
+#include <Library/PciLib.h>
+#include <IndustryStandard/Pci22.h>
+#include <IndustryStandard/X58Ich10.h>
+#include <IndustryStandard/I440FxPiix4.h> // TODO: remove
+
+//
+// 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/LoadLinuxLib/Ia32/JumpToKernel.nasm b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm
new file mode 100644
index 0000000000..3f3cd33c8a
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.nasm
@@ -0,0 +1,41 @@
+; @file
+; Copyright (c) 2006 - 2013 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..c4cc4dd8e7
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
@@ -0,0 +1,52 @@
+/** @file
+ Boot UEFI Linux.
+
+ Copyright (c) 2008 - 2013 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/LoadLinuxLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
new file mode 100644
index 0000000000..89664f4e42
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
@@ -0,0 +1,42 @@
+## @file
+#
+# Copyright (c) 2008 - 2012 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LoadLinuxLib
+ FILE_GUID = 63CC8497-C9D0-46A8-AC08-49DF92A2FF62
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = LoadLinuxLib
+
+#
+# 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
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ MemoryAllocationLib
+ BaseMemoryLib
+
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..79e6b8e7ba
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKernel.nasm
@@ -0,0 +1,85 @@
+; @file
+; Copyright (c) 2006 - 2013 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..92aa038cdd
--- /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 - 2011 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..e4c3b7ccff
--- /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 - 2018 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/SerializeVariablesLib/SerializeVariablesLib.h b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h
new file mode 100644
index 0000000000..7e78cd4b21
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVariablesLib.h
@@ -0,0 +1,33 @@
+/** @file
+ Serialize Variables Library implementation
+
+ Copyright (c) 2009 - 2011 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..25901192b2
--- /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 - 2018 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
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
new file mode 100644
index 0000000000..63b5e52575
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
@@ -0,0 +1,37 @@
+/** @file
+ This driver effectuates OVMF's 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/PlatformDxe/Platform.inf b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
new file mode 100644
index 0000000000..804ab59610
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.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 = PlatformDxe
+ 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/SimicsOpenBoardPkg.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
+ gSimicsX58PlatformConfigGuid
+
+[Depex]
+ gEfiHiiConfigRoutingProtocolGuid AND
+ gEfiHiiDatabaseProtocolGuid AND
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid
diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
new file mode 100644
index 0000000000..6d68cbeb4f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/PlatformDxe/PlatformConfig.h b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
new file mode 100644
index 0000000000..d3f041ddea
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/PlatformDxe/PlatformForms.vfr b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
new file mode 100644
index 0000000000..1c02565ebb
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/SimicsX58PlatformConfig.h>
+#include "Platform.h"
+
+formset
+ guid = SIMICSX58_PLATFORM_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 = SIMICSX58_PLATFORM_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/PlatformPei/Cmos.h b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
new file mode 100644
index 0000000000..616d2d74cb
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
@@ -0,0 +1,50 @@
+/** @file
+ PC/AT CMOS access routines
+
+ Copyright (c) 2006 - 2009 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/PlatformPei/Platform.h b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
new file mode 100644
index 0000000000..5b1a9b5f57
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
@@ -0,0 +1,93 @@
+/** @file
+ Platform PEI module include file.
+
+ Copyright (c) 2006 - 2016 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
+ );
+
+EFI_STATUS
+PeiFvInitialization (
+ 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/PlatformPei/PlatformPei.inf b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
new file mode 100644
index 0000000000..eb8048c655
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
@@ -0,0 +1,109 @@
+## @file
+# Platform PEI driver
+#
+# This module provides platform specific function to detect boot mode.
+# Copyright (c) 2006 - 2018 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformPei
+ 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
+ Fv.c
+ MemDetect.c
+ Platform.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiCpuPkg/UefiCpuPkg.dec
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[Guids]
+ gEfiMemoryTypeInformationGuid
+ gEfiSmmPeiSmramMemoryReserveGuid ## CONSUMES
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ HobLib
+ IoLib
+ PciLib
+ PeiResourcePublicationLib
+ PeiServicesLib
+ PeiServicesTablePointerLib
+ PeimEntryPoint
+ MtrrLib
+ PcdLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
+ gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+ gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
+ 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/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
new file mode 100644
index 0000000000..b9bcb5d2bd
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconPolicyInitLib.inf
@@ -0,0 +1,38 @@
+## @file
+#
+# Copyright (c) 2018 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..da165ac947
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/SiliconPolicyUpdateLib.inf
@@ -0,0 +1,35 @@
+## @file
+#
+# Copyright (c) 2018 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/SimicsOpenBoardPkg.dec b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
new file mode 100644
index 0000000000..17c87aca8c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
@@ -0,0 +1,168 @@
+## @file
+# EFI/Framework Simics X58 platform
+#
+# Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = SimicsX58Pkg
+ PACKAGE_GUID = E6A03E0D-5944-4dc6-9292-090D609EDD3A
+ PACKAGE_VERSION = 0.1
+
+[Includes]
+ Include
+
+[Guids]
+ gSimicsX58PkgTokenSpaceGuid = {0x5b276d20, 0x37d0, 0x4af0, {0x8d, 0x04, 0x47, 0x91, 0x2b, 0x7c, 0x1d, 0x44}}
+ gSimicsX58PlatformConfigGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
+
+[Protocols]
+ gEfiLegacy8259ProtocolGuid = {0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1}}
+ gEfiIsaAcpiProtocolGuid = {0x64a892dc, 0x5561, 0x4536, {0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55}}
+ gEfiIsaIoProtocolGuid = {0x7ee2bd44, 0x3da0, 0x11d4, {0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
+
+[PcdsFixedAtBuild]
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase|0x0|UINT32|0
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize|0x0|UINT32|1
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase|0x0|UINT32|0x15
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize|0x0|UINT32|0x16
+
+ #TODO: Remove these two when we integrate new PlatformPei
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvBase|0x00800000|UINT32|2
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvSize|0x00500000|UINT32|3
+
+ ## 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
+
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase|0x0|UINT32|0x8
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize|0x0|UINT32|0x9
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareFdSize|0x0|UINT32|0xa
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareBlockSize|0|UINT32|0xb
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase|0x0|UINT32|0xc
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase|0x0|UINT32|0xd
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase|0x0|UINT32|0xe
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsFdBaseAddress|0x0|UINT32|0xf
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase|0x0|UINT32|0x11
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesSize|0x0|UINT32|0x12
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|0x0|UINT32|0x13
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize|0x0|UINT32|0x14
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase|0x0|UINT32|0x18
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize|0x0|UINT32|0x19
+ gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT32|0x1a
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd|0x0|UINT32|0x1f
+
+[PcdsDynamic, PcdsDynamicEx]
+
+ # TODO: investigate whether next two Pcds are needed
+ gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|0x28
+ gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0|UINT16|0x1b
+
+ ## The IO port aperture shared by all PCI root bridges.
+ #
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x23
+
+ ## The 32-bit MMIO aperture shared by all PCI root bridges.
+ #
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT64|0x24
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT64|0x25
+
+ ## The 64-bit MMIO aperture shared by all PCI root bridges.
+ #
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x26
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x27
+
+[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
+
+
+[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
+ gSimicsX58PkgTokenSpaceGuid.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 | (gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures & 0xF8) == 0
+ gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0x00010040
\ No newline at end of file
diff --git a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
new file mode 100644
index 0000000000..38a71a3527
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
@@ -0,0 +1,38 @@
+/** @file
+ This driver installs SMBIOS information for OVMF
+
+ 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..6adaf0beb7
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
@@ -0,0 +1,51 @@
+## @file
+# This driver installs SMBIOS information for OVMF
+#
+# 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/SimicsOpenBoardPkg.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] 37+ messages in thread
* Re: [edk2-platform patch 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio
2019-08-09 22:46 ` [edk2-platform patch 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio David Wei
@ 2019-08-15 19:01 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
1 sibling, 0 replies; 37+ messages in thread
From: Nate DeSimone @ 2019-08-15 19:01 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
Hi David,
Here are my comments:
1. What is the purpose of this driver? My guess this is just a dummy driver that provides the EFI_SIO_PROTOCOL and does resource management without actually accessing the SIO?
2. All of the copyright years need to be updated to 2019.
3. Please remove " Contributed-under: TianoCore Contribution Agreement 1.0" from your commit message as it is no longer needed.
4. Please remove interspersed trailing white-space from the following files:
* Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c
* Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c
* Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h
Other than that, looks good! Please send an updated patch.
Thanks,
Nate
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 9, 2019 3:47 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-platform patch 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>
Contributed-under: TianoCore Contribution Agreement 1.0
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..93e8cefe6c
--- /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 - 2016 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..6fa8c53833
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c
@@ -0,0 +1,272 @@
+/** @file
+ Super I/O specific implementation.
+
+ Copyright (c) 2010 - 2016 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..0e308a5f18
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c
@@ -0,0 +1,600 @@
+/** @file
+ EFI Driver following Driver Binding Protocol.
+
+ Copyright (c) 2010 - 2016 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..005d603bdd
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c
@@ -0,0 +1,249 @@
+/** @file
+ Super I/O Interface implementation.
+
+ Copyright (c) 2010 - 2016 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..36a9069f0f
--- /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 - 2016 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..a1f558117e
--- /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 - 2016 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..542b032abb
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h
@@ -0,0 +1,15 @@
+/** @file
+ Super I/O register definitions
+
+ Copyright (c) 2010 - 2016 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..fea2e9c4c5
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h
@@ -0,0 +1,195 @@
+/** @file
+ Super I/O specific header.
+
+ Copyright (c) 2010 - 2016 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..7386cb2e19
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h
@@ -0,0 +1,134 @@
+/** @file
+ Header file for Driver Binding Protocol.
+
+ Copyright (c) 2010 - 2016 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..6f95090b17
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h
@@ -0,0 +1,143 @@
+/** @file
+ Super I/O Interface function declarations.
+
+ Copyright (c) 2010 - 2016 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] 37+ messages in thread
* Re: [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform
2019-08-09 22:46 ` [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform David Wei
@ 2019-08-15 19:28 ` Nate DeSimone
2019-08-19 23:21 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2 siblings, 0 replies; 37+ messages in thread
From: Nate DeSimone @ 2019-08-15 19:28 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
Hi David,
Here are my comments:
1. Please remove " Contributed-under: TianoCore Contribution Agreement 1.0" from your commit message as it is no longer needed.
2. Please don't add this entry: WhiskeylakeURvp = WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
WhiskeylakeOpenBoardPkg does not exist yet, and it will be coming from a separate patch series.
3. Please rename BoardX58ICH10 to follow Pascal casing: BoardX58Ich10
4. Please update edk2-platforms/Platform/Intel/Readme.md to add SimicsOpenBoardPkg to the Board Support list.
Other than that, looks good! Please send an updated patch.
Thanks,
Nate
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 9, 2019 3:47 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-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform
Add build option in build script for SIMICS QSP Platform
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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
Platform/Intel/build.cfg | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg index fc6e4fe824..2ebe09a632 100644
--- a/Platform/Intel/build.cfg
+++ b/Platform/Intel/build.cfg
@@ -54,3 +54,5 @@ NUMBER_OF_PROCESSORS = 0
KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
+WhiskeylakeURvp =
+WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
+BoardX58ICH10 = SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
--
2.16.2.windows.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
2019-08-09 22:46 ` [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform David Wei
@ 2019-08-15 19:38 ` Nate DeSimone
2019-08-15 22:28 ` Nate DeSimone
2019-08-15 22:52 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2 siblings, 1 reply; 37+ messages in thread
From: Nate DeSimone @ 2019-08-15 19:38 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
Hi David,
Here are my comments:
1. All of the copyright years need to be updated to 2019.
2. Please remove " Contributed-under: TianoCore Contribution Agreement 1.0" from your commit message as it is no longer needed.
3. Please rename the directory BoardX58ICH10 to follow Pascal casing: BoardX58Ich10
4. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat - Is this still needed? Can we just use build_bios.py and delete this file?
5. Please rename Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat to follow Pascal casing: GitEdk2X58Ich10.bat
6. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiBoardInitPostMemLib.c - Please rename the following functions to follow Pascal casing:
* X58ICH10BoardInitBeforeSiliconInit --> X58Ich10BoardInitBeforeSiliconInit
* X58ICH10BoardInitAfterSiliconInit --> X58Ich10BoardInitAfterSiliconInit
7. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiBoardInitPreMemLib.c - Please rename the following functions to follow Pascal casing:
* X58ICH10BoardDetect --> X58Ich10BoardDetect
* X58ICH10BoardBootModeDetect --> X58Ich10BoardBootModeDetect
* X58ICH10BoardDebugInit --> X58Ich10BoardDebugInit
* X58ICH10BoardInitBeforeMemoryInit --> X58Ich10BoardInitBeforeMemoryInit
* X58ICH10BoardInitAfterMemoryInit --> X58Ich10BoardInitAfterMemoryInit
8. Please rename Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX58ICH10Detect.c to follow Pascal casing: PeiX58Ich10Detect.c
9. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg - Line 2 - Please rename to follow Pascal casing: BoardX58ICH10 --> BoardX58Ich10
10. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.fdf - Line 295 - Remove the TAB character.
11. Please remove interspersed trailing white-space from the following files:
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOption.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
Other than that, looks good! Please send an updated patch.
Thanks,
Nate
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 9, 2019 3:47 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-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
Overrides/MdeModulePkg/Library/PciHostBridgeLib - it is platform related. should be Customized
Overrides/MdeModulePkg/Logo - the Logo image is Customized
Overrides/MdePkg/Library/BasePciLibCf8 - use the functions specific for SIMICS
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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++
.../Library/PlatformBootManagerLib/BdsPlatform.c | 1553 +++++++++++++++++++
.../Library/PlatformBootManagerLib/PlatformData.c | 35 +
.../Overrides/MdeModulePkg/Logo/Logo.c | 154 ++
.../MdePkg/Library/BasePciLibCf8/PciLib.c | 1221 +++++++++++++++
.../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 | 417 ++++++
.../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++
.../8259InterruptControllerDxe/8259.c | 622 ++++++++
.../Library/PciHostBridgeLib/PciHostBridge.h | 68 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 50 +
.../Library/PlatformBootManagerLib/BdsPlatform.h | 156 ++
.../PlatformBootManagerLib.inf | 69 +
.../Overrides/MdeModulePkg/Logo/Logo.bmp | Bin 0 -> 141078 bytes
.../Overrides/MdeModulePkg/Logo/Logo.idf | 10 +
.../Overrides/MdeModulePkg/Logo/Logo.inf | 28 +
.../Overrides/MdeModulePkg/Logo/Logo.uni | 16 +
.../Overrides/MdeModulePkg/Logo/LogoDxe.inf | 55 +
.../Overrides/MdeModulePkg/Logo/LogoDxe.uni | 16 +
| 14 +
| 14 +
.../Library/BasePciLibCf8/DxePciLibX58Ich10.inf | 40 +
.../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 +
.../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++
.../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++
.../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 73 +
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 281 ++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 +
.../8259InterruptControllerDxe/8259.h | 218 +++
.../8259InterruptControllerDxe/8259.inf | 46 +
.../8259InterruptControllerDxe/Legacy8259.uni | 16 +
| 14 +
41 files changed, 11062 insertions(+)
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.bmp
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
new file mode 100644
index 0000000000..2aaa4b3e90
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -0,0 +1,419 @@
+/** @file
+ OVMF'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 <IndustryStandard/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/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c
new file mode 100644
index 0000000000..0b66862e46
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -0,0 +1,1553 @@
+/** @file
+ Platform BDS customizations.
+
+ Copyright (c) 2004 - 2018 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
+ //
+ BootLogoEnableLogo();
+
+ 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/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c
new file mode 100644
index 0000000000..5f1b16dd56
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/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 - 2017 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/Overrides/MdeModulePkg/Logo/Logo.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
new file mode 100644
index 0000000000..d4a75ad140
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
@@ -0,0 +1,154 @@
+/** @file
+ Logo DXE Driver, install Edkii Platform Logo protocol.
+
+ Copyright (c) 2016 - 2017 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/HiiImageEx.h>
+#include <Protocol/PlatformLogo.h>
+#include <Protocol/HiiPackageList.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+typedef struct {
+ EFI_IMAGE_ID ImageId;
+ EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE Attribute;
+ INTN OffsetX;
+ INTN OffsetY;
+} LOGO_ENTRY;
+
+EFI_HII_IMAGE_EX_PROTOCOL *mHiiImageEx;
+EFI_HII_HANDLE mHiiHandle;
+LOGO_ENTRY mLogos[] = {
+ {
+ IMAGE_TOKEN (IMG_LOGO),
+ EdkiiPlatformLogoDisplayAttributeCenter,
+ 0,
+ 0
+ }
+};
+
+/**
+ Load a platform logo image and return its data and attributes.
+
+ @param This The pointer to this protocol instance.
+ @param Instance The visible image instance is found.
+ @param Image Points to the image.
+ @param Attribute The display attributes of the image returned.
+ @param OffsetX The X offset of the image regarding the Attribute.
+ @param OffsetY The Y offset of the image regarding the Attribute.
+
+ @retval EFI_SUCCESS The image was fetched successfully.
+ @retval EFI_NOT_FOUND The specified image could not be found.
+**/
+EFI_STATUS
+EFIAPI
+GetImage (
+ IN EDKII_PLATFORM_LOGO_PROTOCOL *This,
+ IN OUT UINT32 *Instance,
+ OUT EFI_IMAGE_INPUT *Image,
+ OUT EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE *Attribute,
+ OUT INTN *OffsetX,
+ OUT INTN *OffsetY
+ )
+{
+ UINT32 Current;
+ if (Instance == NULL || Image == NULL ||
+ Attribute == NULL || OffsetX == NULL || OffsetY == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Current = *Instance;
+ if (Current >= ARRAY_SIZE (mLogos)) {
+ return EFI_NOT_FOUND;
+ }
+
+ (*Instance)++;
+ *Attribute = mLogos[Current].Attribute;
+ *OffsetX = mLogos[Current].OffsetX;
+ *OffsetY = mLogos[Current].OffsetY;
+ return mHiiImageEx->GetImageEx (mHiiImageEx, mHiiHandle, mLogos[Current].ImageId, Image);
+}
+
+EDKII_PLATFORM_LOGO_PROTOCOL mPlatformLogo = {
+ GetImage
+};
+
+/**
+ Entrypoint of this module.
+
+ This function is the entrypoint of this module. It installs the Edkii
+ Platform Logo protocol.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeLogo (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_PACKAGE_LIST_HEADER *PackageList;
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
+ EFI_HANDLE Handle;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHiiDatabaseProtocolGuid,
+ NULL,
+ (VOID **) &HiiDatabase
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (
+ &gEfiHiiImageExProtocolGuid,
+ NULL,
+ (VOID **) &mHiiImageEx
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Retrieve HII package list from ImageHandle
+ //
+ Status = gBS->OpenProtocol (
+ ImageHandle,
+ &gEfiHiiPackageListProtocolGuid,
+ (VOID **) &PackageList,
+ ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "HII Image Package with logo not found in PE/COFF resource section\n"));
+ return Status;
+ }
+
+ //
+ // Publish HII package list to HII Database.
+ //
+ Status = HiiDatabase->NewPackageList (
+ HiiDatabase,
+ PackageList,
+ NULL,
+ &mHiiHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEdkiiPlatformLogoProtocolGuid, &mPlatformLogo,
+ NULL
+ );
+ }
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c
new file mode 100644
index 0000000000..7544117a03
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c
@@ -0,0 +1,1221 @@
+/** @file
+ PCI Library functions that use
+ (a) I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles, layering
+ on top of one PCI CF8 Library instance; or
+ (b) PCI Library functions that use the 256 MB PCI Express MMIO window to
+ perform PCI Configuration cycles, layering on PCI Express Library.
+
+ The decision is made in the entry point function, based on the OVMF platform
+ type, and then adhered to during the lifetime of the client module.
+
+ Copyright (C) 2016, Red Hat, Inc.
+ Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <IndustryStandard/X58Ich10.h>
+
+#include <Library/PciLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/PciExpressLib.h>
+#include <Library/PcdLib.h>
+
+STATIC BOOLEAN mRunningOnIch10;
+
+RETURN_STATUS
+EFIAPI
+InitializeConfigAccessMethod (
+ VOID
+ )
+{
+ mRunningOnIch10 = (PcdGet16 (PcdSimicsX58HostBridgePciDevId) ==
+ INTEL_ICH10_DEVICE_ID);
+ return RETURN_SUCCESS;
+}
+
+/**
+ Registers a PCI device so PCI configuration registers may be accessed after
+ SetVirtualAddressMap().
+
+ Registers the PCI device specified by Address so all the PCI configuration registers
+ associated with that PCI device may be accessed after SetVirtualAddressMap() is called.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @retval RETURN_SUCCESS The PCI device was registered for runtime access.
+ @retval RETURN_UNSUPPORTED An attempt was made to call this function
+ after ExitBootServices().
+ @retval RETURN_UNSUPPORTED The resources required to access the PCI device
+ at runtime could not be mapped.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
+ complete the registration.
+
+**/
+RETURN_STATUS
+EFIAPI
+PciRegisterForRuntimeAccess (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRegisterForRuntimeAccess (Address) :
+ PciCf8RegisterForRuntimeAccess (Address);
+}
+
+/**
+ Reads an 8-bit PCI configuration register.
+
+ Reads and returns the 8-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @return The read value from the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciRead8 (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRead8 (Address) :
+ PciCf8Read8 (Address);
+}
+
+/**
+ Writes an 8-bit PCI configuration register.
+
+ Writes the 8-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param Value The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciWrite8 (
+ IN UINTN Address,
+ IN UINT8 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWrite8 (Address, Value) :
+ PciCf8Write8 (Address, Value);
+}
+
+/**
+ Performs a bitwise OR of an 8-bit PCI configuration register with
+ an 8-bit value.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciOr8 (
+ IN UINTN Address,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressOr8 (Address, OrData) :
+ PciCf8Or8 (Address, OrData);
+}
+
+/**
+ Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
+ value.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciAnd8 (
+ IN UINTN Address,
+ IN UINT8 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAnd8 (Address, AndData) :
+ PciCf8And8 (Address, AndData);
+}
+
+/**
+ Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
+ value, followed a bitwise OR with another 8-bit value.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciAndThenOr8 (
+ IN UINTN Address,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAndThenOr8 (Address, AndData, OrData) :
+ PciCf8AndThenOr8 (Address, AndData, OrData);
+}
+
+/**
+ Reads a bit field of a PCI configuration register.
+
+ Reads the bit field in an 8-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Address The PCI configuration register to read.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+
+ @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldRead8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldRead8 (Address, StartBit, EndBit) :
+ PciCf8BitFieldRead8 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes a bit field to a PCI configuration register.
+
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 8-bit register is returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param Value The new value of the bit field.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldWrite8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldWrite8 (Address, StartBit, EndBit, Value) :
+ PciCf8BitFieldWrite8 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
+ writes the result back to the bit field in the 8-bit port.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldOr8 (Address, StartBit, EndBit, OrData) :
+ PciCf8BitFieldOr8 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
+ AND, and writes the result back to the bit field in the 8-bit register.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldAnd8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAnd8 (Address, StartBit, EndBit, AndData) :
+ PciCf8BitFieldAnd8 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
+ bitwise OR, and writes the result back to the bit field in the
+ 8-bit port.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise OR between the read result and
+ the value specified by AndData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldAndThenOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData) :
+ PciCf8BitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads a 16-bit PCI configuration register.
+
+ Reads and returns the 16-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @return The read value from the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciRead16 (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRead16 (Address) :
+ PciCf8Read16 (Address);
+}
+
+/**
+ Writes a 16-bit PCI configuration register.
+
+ Writes the 16-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param Value The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciWrite16 (
+ IN UINTN Address,
+ IN UINT16 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWrite16 (Address, Value) :
+ PciCf8Write16 (Address, Value);
+}
+
+/**
+ Performs a bitwise OR of a 16-bit PCI configuration register with
+ a 16-bit value.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciOr16 (
+ IN UINTN Address,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressOr16 (Address, OrData) :
+ PciCf8Or16 (Address, OrData);
+}
+
+/**
+ Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
+ value.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciAnd16 (
+ IN UINTN Address,
+ IN UINT16 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAnd16 (Address, AndData) :
+ PciCf8And16 (Address, AndData);
+}
+
+/**
+ Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
+ value, followed a bitwise OR with another 16-bit value.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciAndThenOr16 (
+ IN UINTN Address,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAndThenOr16 (Address, AndData, OrData) :
+ PciCf8AndThenOr16 (Address, AndData, OrData);
+}
+
+/**
+ Reads a bit field of a PCI configuration register.
+
+ Reads the bit field in a 16-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Address The PCI configuration register to read.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+
+ @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldRead16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldRead16 (Address, StartBit, EndBit) :
+ PciCf8BitFieldRead16 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes a bit field to a PCI configuration register.
+
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 16-bit register is returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param Value The new value of the bit field.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldWrite16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldWrite16 (Address, StartBit, EndBit, Value) :
+ PciCf8BitFieldWrite16 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
+ writes the result back to the bit field in the 16-bit port.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldOr16 (Address, StartBit, EndBit, OrData) :
+ PciCf8BitFieldOr16 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
+ AND, and writes the result back to the bit field in the 16-bit register.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldAnd16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAnd16 (Address, StartBit, EndBit, AndData) :
+ PciCf8BitFieldAnd16 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
+ bitwise OR, and writes the result back to the bit field in the
+ 16-bit port.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise OR between the read result and
+ the value specified by AndData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldAndThenOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData) :
+ PciCf8BitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads a 32-bit PCI configuration register.
+
+ Reads and returns the 32-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @return The read value from the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciRead32 (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRead32 (Address) :
+ PciCf8Read32 (Address);
+}
+
+/**
+ Writes a 32-bit PCI configuration register.
+
+ Writes the 32-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param Value The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciWrite32 (
+ IN UINTN Address,
+ IN UINT32 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWrite32 (Address, Value) :
+ PciCf8Write32 (Address, Value);
+}
+
+/**
+ Performs a bitwise OR of a 32-bit PCI configuration register with
+ a 32-bit value.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciOr32 (
+ IN UINTN Address,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressOr32 (Address, OrData) :
+ PciCf8Or32 (Address, OrData);
+}
+
+/**
+ Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
+ value.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciAnd32 (
+ IN UINTN Address,
+ IN UINT32 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAnd32 (Address, AndData) :
+ PciCf8And32 (Address, AndData);
+}
+
+/**
+ Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
+ value, followed a bitwise OR with another 32-bit value.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciAndThenOr32 (
+ IN UINTN Address,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAndThenOr32 (Address, AndData, OrData) :
+ PciCf8AndThenOr32 (Address, AndData, OrData);
+}
+
+/**
+ Reads a bit field of a PCI configuration register.
+
+ Reads the bit field in a 32-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Address The PCI configuration register to read.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+
+ @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldRead32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldRead32 (Address, StartBit, EndBit) :
+ PciCf8BitFieldRead32 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes a bit field to a PCI configuration register.
+
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 32-bit register is returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param Value The new value of the bit field.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldWrite32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldWrite32 (Address, StartBit, EndBit, Value) :
+ PciCf8BitFieldWrite32 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
+ writes the result back to the bit field in the 32-bit port.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldOr32 (Address, StartBit, EndBit, OrData) :
+ PciCf8BitFieldOr32 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
+ AND, and writes the result back to the bit field in the 32-bit register.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldAnd32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAnd32 (Address, StartBit, EndBit, AndData) :
+ PciCf8BitFieldAnd32 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
+ bitwise OR, and writes the result back to the bit field in the
+ 32-bit port.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise OR between the read result and
+ the value specified by AndData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldAndThenOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData) :
+ PciCf8BitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads a range of PCI configuration registers into a caller supplied buffer.
+
+ Reads the range of PCI configuration registers specified by StartAddress and
+ Size into the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be read. Size is
+ returned. When possible 32-bit PCI configuration read cycles are used to read
+ from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
+ and 16-bit PCI configuration read cycles may be used at the beginning and the
+ end of the range.
+
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param StartAddress The starting address that encodes the PCI Bus, Device,
+ Function and Register.
+ @param Size The size in bytes of the transfer.
+ @param Buffer The pointer to a buffer receiving the data read.
+
+ @return Size
+
+**/
+UINTN
+EFIAPI
+PciReadBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ OUT VOID *Buffer
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressReadBuffer (StartAddress, Size, Buffer) :
+ PciCf8ReadBuffer (StartAddress, Size, Buffer);
+}
+
+/**
+ Copies the data in a caller supplied buffer to a specified range of PCI
+ configuration space.
+
+ Writes the range of PCI configuration registers specified by StartAddress and
+ Size from the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be written. Size is
+ returned. When possible 32-bit PCI configuration write cycles are used to
+ write from StartAdress to StartAddress + Size. Due to alignment restrictions,
+ 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
+ and the end of the range.
+
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param StartAddress The starting address that encodes the PCI Bus, Device,
+ Function and Register.
+ @param Size The size in bytes of the transfer.
+ @param Buffer The pointer to a buffer containing the data to write.
+
+ @return Size written to StartAddress.
+
+**/
+UINTN
+EFIAPI
+PciWriteBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWriteBuffer (StartAddress, Size, Buffer) :
+ PciCf8WriteBuffer (StartAddress, Size, Buffer);
+}
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..b1d7552792
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
@@ -0,0 +1,1579 @@
+/** @file
+ ACPI Platform Driver
+
+ Copyright (c) 2017 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..a16c13466a
--- /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) 2017 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..8aa10a4a5b
--- /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) 2017 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..aa386ba149
--- /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) 2017 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..12e2feacb4
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c
@@ -0,0 +1,46 @@
+/** @file
+ ACPI WSMT table
+
+ Copyright (c) 2017 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..dd9cc80e42
--- /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 - 2010, 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..c2d82e7324
--- /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 - 2010 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..19ff5209d2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c
@@ -0,0 +1,417 @@
+/** @file
+ Graphics Output Protocol functions for the QEMU video controller.
+
+ Copyright (c) 2007 - 2018 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..fbf40e9eaf
--- /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 - 2010 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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
new file mode 100644
index 0000000000..b57bacdda4
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
@@ -0,0 +1,622 @@
+/** @file
+ This contains the installation function for the driver.
+
+ Copyright (c) 2005 - 2018 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "8259.h"
+
+//
+// Global for the Legacy 8259 Protocol that is produced by this driver
+//
+EFI_LEGACY_8259_PROTOCOL mInterrupt8259 = {
+ Interrupt8259SetVectorBase,
+ Interrupt8259GetMask,
+ Interrupt8259SetMask,
+ Interrupt8259SetMode,
+ Interrupt8259GetVector,
+ Interrupt8259EnableIrq,
+ Interrupt8259DisableIrq,
+ Interrupt8259GetInterruptLine,
+ Interrupt8259EndOfInterrupt
+};
+
+//
+// Global for the handle that the Legacy 8259 Protocol is installed
+//
+EFI_HANDLE m8259Handle = NULL;
+
+UINT8 mMasterBase = 0xff;
+UINT8 mSlaveBase = 0xff;
+EFI_8259_MODE mMode = Efi8259ProtectedMode;
+UINT16 mProtectedModeMask = 0xffff;
+UINT16 mLegacyModeMask;
+UINT16 mProtectedModeEdgeLevel = 0x0000;
+UINT16 mLegacyModeEdgeLevel;
+
+//
+// Worker Functions
+//
+
+/**
+ Write to mask and edge/level triggered registers of master and slave 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));
+}
+
+/**
+ Read from mask and edge/level triggered registers of master and slave PICs.
+
+ @param[out] Mask low byte for master PIC mask register,
+ high byte for slave PIC mask register.
+ @param[out] EdgeLevel low byte for master PIC edge/level triggered register,
+ high byte for slave PIC edge/level triggered register.
+
+**/
+VOID
+Interrupt8259ReadMask (
+ OUT UINT16 *Mask,
+ OUT UINT16 *EdgeLevel
+ )
+{
+ UINT16 MasterValue;
+ UINT16 SlaveValue;
+
+ if (Mask != NULL) {
+ MasterValue = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
+ SlaveValue = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
+
+ *Mask = (UINT16) (MasterValue | (SlaveValue << 8));
+ }
+
+ if (EdgeLevel != NULL) {
+ MasterValue = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER);
+ SlaveValue = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE);
+
+ *EdgeLevel = (UINT16) (MasterValue | (SlaveValue << 8));
+ }
+}
+
+//
+// Legacy 8259 Protocol Interface Functions
+//
+
+/**
+ Sets the base address for the 8259 master and slave PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
+ @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing to the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetVectorBase (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT8 MasterBase,
+ IN UINT8 SlaveBase
+ )
+{
+ UINT8 Mask;
+ EFI_TPL OriginalTpl;
+
+ OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+ //
+ // Set vector base for slave PIC
+ //
+ if (SlaveBase != mSlaveBase) {
+ mSlaveBase = SlaveBase;
+
+ //
+ // Initialization sequence is needed for setting vector base.
+ //
+
+ //
+ // Preserve interrtup mask register before initialization sequence
+ // because it will be cleared during initialization
+ //
+ Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
+
+ //
+ // ICW1: cascade mode, ICW4 write required
+ //
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, 0x11);
+
+ //
+ // ICW2: new vector base (must be multiple of 8)
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, mSlaveBase);
+
+ //
+ // ICW3: slave indentification code must be 2
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x02);
+
+ //
+ // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x01);
+
+ //
+ // Restore interrupt mask register
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, Mask);
+ }
+
+ //
+ // Set vector base for master PIC
+ //
+ if (MasterBase != mMasterBase) {
+ mMasterBase = MasterBase;
+
+ //
+ // Initialization sequence is needed for setting vector base.
+ //
+
+ //
+ // Preserve interrtup mask register before initialization sequence
+ // because it will be cleared during initialization
+ //
+ Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
+
+ //
+ // ICW1: cascade mode, ICW4 write required
+ //
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, 0x11);
+
+ //
+ // ICW2: new vector base (must be multiple of 8)
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, mMasterBase);
+
+ //
+ // ICW3: slave PIC is cascaded on IRQ2
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x04);
+
+ //
+ // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x01);
+
+ //
+ // Restore interrupt mask register
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, Mask);
+ }
+
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI);
+
+ gBS->RestoreTPL (OriginalTpl);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ OUT UINT16 *LegacyMask, OPTIONAL
+ OUT UINT16 *LegacyEdgeLevel, OPTIONAL
+ OUT UINT16 *ProtectedMask, OPTIONAL
+ OUT UINT16 *ProtectedEdgeLevel OPTIONAL
+ )
+{
+ if (LegacyMask != NULL) {
+ *LegacyMask = mLegacyModeMask;
+ }
+
+ if (LegacyEdgeLevel != NULL) {
+ *LegacyEdgeLevel = mLegacyModeEdgeLevel;
+ }
+
+ if (ProtectedMask != NULL) {
+ *ProtectedMask = mProtectedModeMask;
+ }
+
+ if (ProtectedEdgeLevel != NULL) {
+ *ProtectedEdgeLevel = mProtectedModeEdgeLevel;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT16 *LegacyMask, OPTIONAL
+ IN UINT16 *LegacyEdgeLevel, OPTIONAL
+ IN UINT16 *ProtectedMask, OPTIONAL
+ IN UINT16 *ProtectedEdgeLevel OPTIONAL
+ )
+{
+ if (LegacyMask != NULL) {
+ mLegacyModeMask = *LegacyMask;
+ }
+
+ if (LegacyEdgeLevel != NULL) {
+ mLegacyModeEdgeLevel = *LegacyEdgeLevel;
+ }
+
+ if (ProtectedMask != NULL) {
+ mProtectedModeMask = *ProtectedMask;
+ }
+
+ if (ProtectedEdgeLevel != NULL) {
+ mProtectedModeEdgeLevel = *ProtectedEdgeLevel;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Sets the mode of the PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Mode 16-bit real or 32-bit protected mode.
+ @param[in] Mask The value with which to set the interrupt mask.
+ @param[in] EdgeLevel The value with which to set the edge/level mask.
+
+ @retval EFI_SUCCESS The mode was set successfully.
+ @retval EFI_INVALID_PARAMETER The mode was not set.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMode (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_MODE Mode,
+ IN UINT16 *Mask, OPTIONAL
+ IN UINT16 *EdgeLevel OPTIONAL
+ )
+{
+ if (Mode == mMode) {
+ return EFI_SUCCESS;
+ }
+
+ if (Mode == Efi8259LegacyMode) {
+ //
+ // In Efi8259ProtectedMode, mask and edge/level trigger registers should
+ // be changed through this protocol, so we can track them in the
+ // corresponding module variables.
+ //
+ Interrupt8259ReadMask (&mProtectedModeMask, &mProtectedModeEdgeLevel);
+
+ if (Mask != NULL) {
+ //
+ // Update the Mask for the new mode
+ //
+ mLegacyModeMask = *Mask;
+ }
+
+ if (EdgeLevel != NULL) {
+ //
+ // Update the Edge/Level triggered mask for the new mode
+ //
+ mLegacyModeEdgeLevel = *EdgeLevel;
+ }
+
+ mMode = Mode;
+
+ //
+ // Write new legacy mode mask/trigger level
+ //
+ Interrupt8259WriteMask (mLegacyModeMask, mLegacyModeEdgeLevel);
+
+ return EFI_SUCCESS;
+ }
+
+ if (Mode == Efi8259ProtectedMode) {
+ //
+ // Save the legacy mode mask/trigger level
+ //
+ Interrupt8259ReadMask (&mLegacyModeMask, &mLegacyModeEdgeLevel);
+ //
+ // Always force Timer to be enabled after return from 16-bit code.
+ // This always insures that on next entry, timer is counting.
+ //
+ mLegacyModeMask &= 0xFFFE;
+
+ if (Mask != NULL) {
+ //
+ // Update the Mask for the new mode
+ //
+ mProtectedModeMask = *Mask;
+ }
+
+ if (EdgeLevel != NULL) {
+ //
+ // Update the Edge/Level triggered mask for the new mode
+ //
+ mProtectedModeEdgeLevel = *EdgeLevel;
+ }
+
+ mMode = Mode;
+
+ //
+ // Write new protected mode mask/trigger level
+ //
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ Translates the IRQ into a vector.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[out] Vector The vector that is assigned to the IRQ.
+
+ @retval EFI_SUCCESS The Vector that matches Irq was returned.
+ @retval EFI_INVALID_PARAMETER Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetVector (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ OUT UINT8 *Vector
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Irq <= Efi8259Irq7) {
+ *Vector = (UINT8) (mMasterBase + Irq);
+ } else {
+ *Vector = (UINT8) (mSlaveBase + (Irq - Efi8259Irq8));
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Enables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
+
+ @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EnableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ IN BOOLEAN LevelTriggered
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ mProtectedModeMask = (UINT16) (mProtectedModeMask & ~(1 << Irq));
+ if (LevelTriggered) {
+ mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel | (1 << Irq));
+ } else {
+ mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq));
+ }
+
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Disables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259DisableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ mProtectedModeMask = (UINT16) (mProtectedModeMask | (1 << Irq));
+
+ mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq));
+
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Reads the PCI configuration space to get the interrupt number that is assigned to the card.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] PciHandle PCI function for which to return the vector.
+ @param[out] Vector IRQ number that corresponds to the interrupt line.
+
+ @retval EFI_SUCCESS The interrupt line value was read successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetInterruptLine (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT UINT8 *Vector
+ )
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 InterruptLine;
+ EFI_STATUS Status;
+
+ Status = gBS->HandleProtocol (
+ PciHandle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ PCI_INT_LINE_OFFSET,
+ 1,
+ &InterruptLine
+ );
+ //
+ // Interrupt line is same location for standard PCI cards, standard
+ // bridge and CardBus bridge.
+ //
+ *Vector = InterruptLine;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Issues the End of Interrupt (EOI) commands to PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq The interrupt for which to issue the EOI command.
+
+ @retval EFI_SUCCESS The EOI command was issued.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EndOfInterrupt (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Irq >= Efi8259Irq8) {
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);
+ }
+
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Driver Entry point.
+
+ @param[in] ImageHandle ImageHandle of the loaded driver.
+ @param[in] SystemTable Pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS One or more of the drivers returned a success code.
+ @retval !EFI_SUCCESS Error installing Legacy 8259 Protocol.
+
+**/
+EFI_STATUS
+EFIAPI
+Install8259 (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_8259_IRQ Irq;
+
+ //
+ // Initialze mask values from PCDs
+ //
+ mLegacyModeMask = PcdGet16 (Pcd8259LegacyModeMask);
+ mLegacyModeEdgeLevel = PcdGet16 (Pcd8259LegacyModeEdgeLevel);
+
+ //
+ // Clear all pending interrupt
+ //
+ for (Irq = Efi8259Irq0; Irq <= Efi8259Irq15; Irq++) {
+ Interrupt8259EndOfInterrupt (&mInterrupt8259, Irq);
+ }
+
+ //
+ // Set the 8259 Master base to 0x68 and the 8259 Slave base to 0x70
+ //
+ Status = Interrupt8259SetVectorBase (&mInterrupt8259, PROTECTED_MODE_BASE_VECTOR_MASTER, PROTECTED_MODE_BASE_VECTOR_SLAVE);
+
+ //
+ // Set all 8259 interrupts to edge triggered and disabled
+ //
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ //
+ // Install 8259 Protocol onto a new handle
+ //
+ Status = gBS->InstallProtocolInterface (
+ &m8259Handle,
+ &gEfiLegacy8259ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mInterrupt8259
+ );
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h
new file mode 100644
index 0000000000..3bf31067fa
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h
@@ -0,0 +1,68 @@
+/** @file
+ Header file of OVMF instance of PciHostBridgeLib.
+
+ Copyright (c) 2016 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/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
new file mode 100644
index 0000000000..8c6de3dca6
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -0,0 +1,50 @@
+## @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/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ PciLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h
new file mode 100644
index 0000000000..1fb031b752
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h
@@ -0,0 +1,156 @@
+/** @file
+ Platform BDS customizations include file.
+
+ Copyright (c) 2006 - 2017 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
+ );
+
+#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644
index 0000000000..55da35e87d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -0,0 +1,69 @@
+## @file
+# Platform BDS customizations library.
+#
+# Copyright (c) 2007 - 2018 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/SimicsOpenBoardPkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ UefiBootManagerLib
+ BootLogoLib
+ DevicePathLib
+ PciLib
+ NvVarsFileLib
+ LoadLinuxLib
+ UefiLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent
+ gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+ gSimicsX58PkgTokenSpaceGuid.PcdShellFile
+
+[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/Overrides/MdeModulePkg/Logo/Logo.bmp b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/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/Overrides/MdeModulePkg/Logo/Logo.idf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
new file mode 100644
index 0000000000..1f79332020
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
@@ -0,0 +1,10 @@
+// /** @file
+// Platform Logo image definition file.
+//
+// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#image IMG_LOGO Logo.bmp
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
new file mode 100644
index 0000000000..3380f3c1d5
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
@@ -0,0 +1,28 @@
+## @file
+# The default logo bitmap picture shown on setup screen, which is corresponding to gEfiDefaultBmpLogoGuid.
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Logo
+ MODULE_UNI_FILE = Logo.uni
+ FILE_GUID = 7BB28B99-61BB-11D5-9A5D-0090273FC14D
+ 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 ARM AARCH64
+#
+
+[Binaries]
+ BIN|Logo.bmp|*
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ LogoExtra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
new file mode 100644
index 0000000000..9d1bbaffa9
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
@@ -0,0 +1,16 @@
+// /** @file
+// The default logo bitmap picture shown on setup screen, which is corresponding to gEfiDefaultBmpLogoGuid.
+//
+// This module provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid.
+//
+// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid."
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf
new file mode 100644
index 0000000000..01102b138f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf
@@ -0,0 +1,55 @@
+## @file
+# The default logo bitmap picture shown on setup screen.
+#
+# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LogoDxe
+ MODULE_UNI_FILE = LogoDxe.uni
+ FILE_GUID = F74D20EE-37E7-48FC-97F7-9B1047749C69
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeLogo
+#
+# This flag specifies whether HII resource section is generated into PE image.
+#
+ UEFI_HII_RESOURCE_SECTION = TRUE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ Logo.bmp
+ Logo.c
+ Logo.idf
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ DebugLib
+
+[Protocols]
+ gEfiHiiDatabaseProtocolGuid ## CONSUMES
+ gEfiHiiImageExProtocolGuid ## CONSUMES
+ gEfiHiiPackageListProtocolGuid ## PRODUCES CONSUMES
+ gEdkiiPlatformLogoProtocolGuid ## PRODUCES
+
+[Depex]
+ gEfiHiiDatabaseProtocolGuid AND
+ gEfiHiiImageExProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ LogoDxeExtra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni
new file mode 100644
index 0000000000..9635701b60
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni
@@ -0,0 +1,16 @@
+// /** @file
+// The default logo bitmap picture shown on setup screen.
+//
+// This module provides the default logo bitmap picture shown on setup screen, through EDKII Platform Logo protocol.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides the default logo bitmap picture shown on setup screen."
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module provides the default logo bitmap picture shown on setup screen, through EDKII Platform Logo protocol."
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni
new file mode 100644
index 0000000000..c6ea34b81d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Logo Localized Strings and Content
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Logo Image File"
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni
new file mode 100644
index 0000000000..041179fb75
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Logo Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Logo Image File"
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
new file mode 100644
index 0000000000..e5ca95e20e
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
@@ -0,0 +1,40 @@
+## @file
+# An instance of the PCI Library that is based on both the PCI CF8 Library and
+# the PCI Express Library.
+#
+# This PciLib instance caches the SimicsX58 platform type (X58-ICH10) in
+# its entry point function, then delegates function calls to one of the
+# PciCf8Lib or PciExpressLib "backends" as appropriate.
+#
+# Copyright (C) 2016, Red Hat, Inc.
+# Copyright (c) 2007 - 2014 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxePciLibX58Ich10
+ FILE_GUID = FC214B5D-B5B5-4E54-9B28-5E94532E5E2A
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PciLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION
+ CONSTRUCTOR = InitializeConfigAccessMethod
+
+# VALID_ARCHITECTURES = IA32 X64
+
+[Sources]
+ PciLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ PcdLib
+ PciCf8Lib
+ PciExpressLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
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..2deb2a88eb
--- /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) 2017 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..b4b52b6622
--- /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) 2017 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..8370559016
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
@@ -0,0 +1,73 @@
+## @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/SimicsOpenBoardPkg.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
+ gSimicsX58PkgTokenSpaceGuid.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..cb2a60d827
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm
@@ -0,0 +1,281 @@
+;------------------------------------------------------------------------------
+; @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
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
new file mode 100644
index 0000000000..a9673f9c87
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
@@ -0,0 +1,218 @@
+/** @file
+ Driver implementing the Tiano Legacy 8259 Protocol
+
+Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _8259_H__
+#define _8259_H__
+
+#include <Protocol/Legacy8259.h>
+#include <Protocol/PciIo.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+// 8259 Hardware definitions
+
+#define LEGACY_MODE_BASE_VECTOR_MASTER 0x08
+#define LEGACY_MODE_BASE_VECTOR_SLAVE 0x70
+
+#define PROTECTED_MODE_BASE_VECTOR_MASTER 0x68
+#define PROTECTED_MODE_BASE_VECTOR_SLAVE 0x70
+
+#define LEGACY_8259_CONTROL_REGISTER_MASTER 0x20
+#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
+#define LEGACY_8259_CONTROL_REGISTER_SLAVE 0xA0
+#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
+
+#define LEGACY_8259_EOI 0x20
+
+// Protocol Function Prototypes
+
+/**
+ Sets the base address for the 8259 master and slave PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
+ @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing to the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetVectorBase (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT8 MasterBase,
+ IN UINT8 SlaveBase
+ );
+
+/**
+ Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ OUT UINT16 *LegacyMask, OPTIONAL
+ OUT UINT16 *LegacyEdgeLevel, OPTIONAL
+ OUT UINT16 *ProtectedMask, OPTIONAL
+ OUT UINT16 *ProtectedEdgeLevel OPTIONAL
+ );
+
+/**
+ Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT16 *LegacyMask, OPTIONAL
+ IN UINT16 *LegacyEdgeLevel, OPTIONAL
+ IN UINT16 *ProtectedMask, OPTIONAL
+ IN UINT16 *ProtectedEdgeLevel OPTIONAL
+ );
+
+/**
+ Sets the mode of the PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Mode 16-bit real or 32-bit protected mode.
+ @param[in] Mask The value with which to set the interrupt mask.
+ @param[in] EdgeLevel The value with which to set the edge/level mask.
+
+ @retval EFI_SUCCESS The mode was set successfully.
+ @retval EFI_INVALID_PARAMETER The mode was not set.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMode (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_MODE Mode,
+ IN UINT16 *Mask, OPTIONAL
+ IN UINT16 *EdgeLevel OPTIONAL
+ );
+
+/**
+ Translates the IRQ into a vector.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[out] Vector The vector that is assigned to the IRQ.
+
+ @retval EFI_SUCCESS The Vector that matches Irq was returned.
+ @retval EFI_INVALID_PARAMETER Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetVector (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ OUT UINT8 *Vector
+ );
+
+/**
+ Enables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
+
+ @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EnableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ IN BOOLEAN LevelTriggered
+ );
+
+/**
+ Disables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259DisableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ );
+
+/**
+ Reads the PCI configuration space to get the interrupt number that is assigned to the card.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] PciHandle PCI function for which to return the vector.
+ @param[out] Vector IRQ number that corresponds to the interrupt line.
+
+ @retval EFI_SUCCESS The interrupt line value was read successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetInterruptLine (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT UINT8 *Vector
+ );
+
+/**
+ Issues the End of Interrupt (EOI) commands to PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq The interrupt for which to issue the EOI command.
+
+ @retval EFI_SUCCESS The EOI command was issued.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EndOfInterrupt (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ );
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
new file mode 100644
index 0000000000..e66b21c914
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
@@ -0,0 +1,46 @@
+## @file
+# 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
+#
+# Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Legacy8259
+ MODULE_UNI_FILE = Legacy8259.uni
+ FILE_GUID = 79CA4208-BBA1-4a9a-8456-E1E66A81484E
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = Install8259
+
+[Sources]
+ 8259.c
+ 8259.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ PcAtChipsetPkg/PcAtChipsetPkg.dec
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ DebugLib
+ UefiDriverEntryPoint
+ IoLib
+ PcdLib
+
+[Protocols]
+ gEfiLegacy8259ProtocolGuid ## PRODUCES
+ gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMES
+
+[Pcd]
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask ## CONSUMES
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel ## CONSUMES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ Legacy8259Extra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
new file mode 100644
index 0000000000..d035292419
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
@@ -0,0 +1,16 @@
+// /** @file
+// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
+//
+// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
+//
+// Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "8259 Interrupt Controller driver that provides Legacy 8259 protocol"
+
+#string STR_MODULE_DESCRIPTION #language en-US "8259 Interrupt Controller driver that provides Legacy 8259 protocol."
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
new file mode 100644
index 0000000000..ee43f6923c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Legacy8259 Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Legacy 8259 Interrupt Controller DXE Driver"
+
+
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
2019-08-15 19:38 ` Nate DeSimone
@ 2019-08-15 22:28 ` Nate DeSimone
0 siblings, 0 replies; 37+ messages in thread
From: Nate DeSimone @ 2019-08-15 22:28 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
Sorry this one was intended for patch 6 not patch 5.
-----Original Message-----
From: Desimone, Nathaniel L
Sent: Thursday, August 15, 2019 12:38 PM
To: Wei, David Y <david.y.wei@intel.com>; 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>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: RE: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
Hi David,
Here are my comments:
1. All of the copyright years need to be updated to 2019.
2. Please remove " Contributed-under: TianoCore Contribution Agreement 1.0" from your commit message as it is no longer needed.
3. Please rename the directory BoardX58ICH10 to follow Pascal casing: BoardX58Ich10
4. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat - Is this still needed? Can we just use build_bios.py and delete this file?
5. Please rename Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat to follow Pascal casing: GitEdk2X58Ich10.bat
6. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiBoardInitPostMemLib.c - Please rename the following functions to follow Pascal casing:
* X58ICH10BoardInitBeforeSiliconInit --> X58Ich10BoardInitBeforeSiliconInit
* X58ICH10BoardInitAfterSiliconInit --> X58Ich10BoardInitAfterSiliconInit
7. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiBoardInitPreMemLib.c - Please rename the following functions to follow Pascal casing:
* X58ICH10BoardDetect --> X58Ich10BoardDetect
* X58ICH10BoardBootModeDetect --> X58Ich10BoardBootModeDetect
* X58ICH10BoardDebugInit --> X58Ich10BoardDebugInit
* X58ICH10BoardInitBeforeMemoryInit --> X58Ich10BoardInitBeforeMemoryInit
* X58ICH10BoardInitAfterMemoryInit --> X58Ich10BoardInitAfterMemoryInit
8. Please rename Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX58ICH10Detect.c to follow Pascal casing: PeiX58Ich10Detect.c
9. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg - Line 2 - Please rename to follow Pascal casing: BoardX58ICH10 --> BoardX58Ich10
10. Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.fdf - Line 295 - Remove the TAB character.
11. Please remove interspersed trailing white-space from the following files:
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOption.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.dsc
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
* Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
Other than that, looks good! Please send an updated patch.
Thanks,
Nate
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 9, 2019 3:47 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-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
Overrides/MdeModulePkg/Library/PciHostBridgeLib - it is platform related. should be Customized
Overrides/MdeModulePkg/Logo - the Logo image is Customized
Overrides/MdePkg/Library/BasePciLibCf8 - use the functions specific for SIMICS
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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++
.../Library/PlatformBootManagerLib/BdsPlatform.c | 1553 +++++++++++++++++++
.../Library/PlatformBootManagerLib/PlatformData.c | 35 +
.../Overrides/MdeModulePkg/Logo/Logo.c | 154 ++
.../MdePkg/Library/BasePciLibCf8/PciLib.c | 1221 +++++++++++++++
.../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 | 417 ++++++
.../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++
.../8259InterruptControllerDxe/8259.c | 622 ++++++++
.../Library/PciHostBridgeLib/PciHostBridge.h | 68 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 50 +
.../Library/PlatformBootManagerLib/BdsPlatform.h | 156 ++
.../PlatformBootManagerLib.inf | 69 +
.../Overrides/MdeModulePkg/Logo/Logo.bmp | Bin 0 -> 141078 bytes
.../Overrides/MdeModulePkg/Logo/Logo.idf | 10 +
.../Overrides/MdeModulePkg/Logo/Logo.inf | 28 +
.../Overrides/MdeModulePkg/Logo/Logo.uni | 16 +
.../Overrides/MdeModulePkg/Logo/LogoDxe.inf | 55 +
.../Overrides/MdeModulePkg/Logo/LogoDxe.uni | 16 +
| 14 +
| 14 +
.../Library/BasePciLibCf8/DxePciLibX58Ich10.inf | 40 +
.../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 +
.../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++
.../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++
.../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 73 +
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 281 ++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 +
.../8259InterruptControllerDxe/8259.h | 218 +++
.../8259InterruptControllerDxe/8259.inf | 46 +
.../8259InterruptControllerDxe/Legacy8259.uni | 16 +
| 14 +
41 files changed, 11062 insertions(+)
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.bmp
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
new file mode 100644
index 0000000000..2aaa4b3e90
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -0,0 +1,419 @@
+/** @file
+ OVMF'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 <IndustryStandard/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/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c
new file mode 100644
index 0000000000..0b66862e46
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -0,0 +1,1553 @@
+/** @file
+ Platform BDS customizations.
+
+ Copyright (c) 2004 - 2018 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
+ //
+ BootLogoEnableLogo();
+
+ 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/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c
new file mode 100644
index 0000000000..5f1b16dd56
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/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 - 2017 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/Overrides/MdeModulePkg/Logo/Logo.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
new file mode 100644
index 0000000000..d4a75ad140
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
@@ -0,0 +1,154 @@
+/** @file
+ Logo DXE Driver, install Edkii Platform Logo protocol.
+
+ Copyright (c) 2016 - 2017 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/HiiImageEx.h>
+#include <Protocol/PlatformLogo.h>
+#include <Protocol/HiiPackageList.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+typedef struct {
+ EFI_IMAGE_ID ImageId;
+ EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE Attribute;
+ INTN OffsetX;
+ INTN OffsetY;
+} LOGO_ENTRY;
+
+EFI_HII_IMAGE_EX_PROTOCOL *mHiiImageEx;
+EFI_HII_HANDLE mHiiHandle;
+LOGO_ENTRY mLogos[] = {
+ {
+ IMAGE_TOKEN (IMG_LOGO),
+ EdkiiPlatformLogoDisplayAttributeCenter,
+ 0,
+ 0
+ }
+};
+
+/**
+ Load a platform logo image and return its data and attributes.
+
+ @param This The pointer to this protocol instance.
+ @param Instance The visible image instance is found.
+ @param Image Points to the image.
+ @param Attribute The display attributes of the image returned.
+ @param OffsetX The X offset of the image regarding the Attribute.
+ @param OffsetY The Y offset of the image regarding the Attribute.
+
+ @retval EFI_SUCCESS The image was fetched successfully.
+ @retval EFI_NOT_FOUND The specified image could not be found.
+**/
+EFI_STATUS
+EFIAPI
+GetImage (
+ IN EDKII_PLATFORM_LOGO_PROTOCOL *This,
+ IN OUT UINT32 *Instance,
+ OUT EFI_IMAGE_INPUT *Image,
+ OUT EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE *Attribute,
+ OUT INTN *OffsetX,
+ OUT INTN *OffsetY
+ )
+{
+ UINT32 Current;
+ if (Instance == NULL || Image == NULL ||
+ Attribute == NULL || OffsetX == NULL || OffsetY == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Current = *Instance;
+ if (Current >= ARRAY_SIZE (mLogos)) {
+ return EFI_NOT_FOUND;
+ }
+
+ (*Instance)++;
+ *Attribute = mLogos[Current].Attribute;
+ *OffsetX = mLogos[Current].OffsetX;
+ *OffsetY = mLogos[Current].OffsetY;
+ return mHiiImageEx->GetImageEx (mHiiImageEx, mHiiHandle, mLogos[Current].ImageId, Image);
+}
+
+EDKII_PLATFORM_LOGO_PROTOCOL mPlatformLogo = {
+ GetImage
+};
+
+/**
+ Entrypoint of this module.
+
+ This function is the entrypoint of this module. It installs the Edkii
+ Platform Logo protocol.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeLogo (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_PACKAGE_LIST_HEADER *PackageList;
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
+ EFI_HANDLE Handle;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHiiDatabaseProtocolGuid,
+ NULL,
+ (VOID **) &HiiDatabase
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (
+ &gEfiHiiImageExProtocolGuid,
+ NULL,
+ (VOID **) &mHiiImageEx
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Retrieve HII package list from ImageHandle
+ //
+ Status = gBS->OpenProtocol (
+ ImageHandle,
+ &gEfiHiiPackageListProtocolGuid,
+ (VOID **) &PackageList,
+ ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "HII Image Package with logo not found in PE/COFF resource section\n"));
+ return Status;
+ }
+
+ //
+ // Publish HII package list to HII Database.
+ //
+ Status = HiiDatabase->NewPackageList (
+ HiiDatabase,
+ PackageList,
+ NULL,
+ &mHiiHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEdkiiPlatformLogoProtocolGuid, &mPlatformLogo,
+ NULL
+ );
+ }
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c
new file mode 100644
index 0000000000..7544117a03
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c
@@ -0,0 +1,1221 @@
+/** @file
+ PCI Library functions that use
+ (a) I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles, layering
+ on top of one PCI CF8 Library instance; or
+ (b) PCI Library functions that use the 256 MB PCI Express MMIO window to
+ perform PCI Configuration cycles, layering on PCI Express Library.
+
+ The decision is made in the entry point function, based on the OVMF platform
+ type, and then adhered to during the lifetime of the client module.
+
+ Copyright (C) 2016, Red Hat, Inc.
+ Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <IndustryStandard/X58Ich10.h>
+
+#include <Library/PciLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/PciExpressLib.h>
+#include <Library/PcdLib.h>
+
+STATIC BOOLEAN mRunningOnIch10;
+
+RETURN_STATUS
+EFIAPI
+InitializeConfigAccessMethod (
+ VOID
+ )
+{
+ mRunningOnIch10 = (PcdGet16 (PcdSimicsX58HostBridgePciDevId) ==
+ INTEL_ICH10_DEVICE_ID);
+ return RETURN_SUCCESS;
+}
+
+/**
+ Registers a PCI device so PCI configuration registers may be accessed after
+ SetVirtualAddressMap().
+
+ Registers the PCI device specified by Address so all the PCI configuration registers
+ associated with that PCI device may be accessed after SetVirtualAddressMap() is called.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @retval RETURN_SUCCESS The PCI device was registered for runtime access.
+ @retval RETURN_UNSUPPORTED An attempt was made to call this function
+ after ExitBootServices().
+ @retval RETURN_UNSUPPORTED The resources required to access the PCI device
+ at runtime could not be mapped.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
+ complete the registration.
+
+**/
+RETURN_STATUS
+EFIAPI
+PciRegisterForRuntimeAccess (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRegisterForRuntimeAccess (Address) :
+ PciCf8RegisterForRuntimeAccess (Address);
+}
+
+/**
+ Reads an 8-bit PCI configuration register.
+
+ Reads and returns the 8-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @return The read value from the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciRead8 (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRead8 (Address) :
+ PciCf8Read8 (Address);
+}
+
+/**
+ Writes an 8-bit PCI configuration register.
+
+ Writes the 8-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param Value The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciWrite8 (
+ IN UINTN Address,
+ IN UINT8 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWrite8 (Address, Value) :
+ PciCf8Write8 (Address, Value);
+}
+
+/**
+ Performs a bitwise OR of an 8-bit PCI configuration register with
+ an 8-bit value.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciOr8 (
+ IN UINTN Address,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressOr8 (Address, OrData) :
+ PciCf8Or8 (Address, OrData);
+}
+
+/**
+ Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
+ value.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciAnd8 (
+ IN UINTN Address,
+ IN UINT8 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAnd8 (Address, AndData) :
+ PciCf8And8 (Address, AndData);
+}
+
+/**
+ Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
+ value, followed a bitwise OR with another 8-bit value.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciAndThenOr8 (
+ IN UINTN Address,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAndThenOr8 (Address, AndData, OrData) :
+ PciCf8AndThenOr8 (Address, AndData, OrData);
+}
+
+/**
+ Reads a bit field of a PCI configuration register.
+
+ Reads the bit field in an 8-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Address The PCI configuration register to read.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+
+ @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldRead8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldRead8 (Address, StartBit, EndBit) :
+ PciCf8BitFieldRead8 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes a bit field to a PCI configuration register.
+
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 8-bit register is returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param Value The new value of the bit field.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldWrite8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldWrite8 (Address, StartBit, EndBit, Value) :
+ PciCf8BitFieldWrite8 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
+ writes the result back to the bit field in the 8-bit port.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldOr8 (Address, StartBit, EndBit, OrData) :
+ PciCf8BitFieldOr8 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
+ AND, and writes the result back to the bit field in the 8-bit register.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldAnd8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAnd8 (Address, StartBit, EndBit, AndData) :
+ PciCf8BitFieldAnd8 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
+ bitwise OR, and writes the result back to the bit field in the
+ 8-bit port.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise OR between the read result and
+ the value specified by AndData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldAndThenOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData) :
+ PciCf8BitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads a 16-bit PCI configuration register.
+
+ Reads and returns the 16-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @return The read value from the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciRead16 (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRead16 (Address) :
+ PciCf8Read16 (Address);
+}
+
+/**
+ Writes a 16-bit PCI configuration register.
+
+ Writes the 16-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param Value The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciWrite16 (
+ IN UINTN Address,
+ IN UINT16 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWrite16 (Address, Value) :
+ PciCf8Write16 (Address, Value);
+}
+
+/**
+ Performs a bitwise OR of a 16-bit PCI configuration register with
+ a 16-bit value.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciOr16 (
+ IN UINTN Address,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressOr16 (Address, OrData) :
+ PciCf8Or16 (Address, OrData);
+}
+
+/**
+ Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
+ value.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciAnd16 (
+ IN UINTN Address,
+ IN UINT16 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAnd16 (Address, AndData) :
+ PciCf8And16 (Address, AndData);
+}
+
+/**
+ Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
+ value, followed a bitwise OR with another 16-bit value.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciAndThenOr16 (
+ IN UINTN Address,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAndThenOr16 (Address, AndData, OrData) :
+ PciCf8AndThenOr16 (Address, AndData, OrData);
+}
+
+/**
+ Reads a bit field of a PCI configuration register.
+
+ Reads the bit field in a 16-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Address The PCI configuration register to read.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+
+ @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldRead16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldRead16 (Address, StartBit, EndBit) :
+ PciCf8BitFieldRead16 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes a bit field to a PCI configuration register.
+
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 16-bit register is returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param Value The new value of the bit field.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldWrite16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldWrite16 (Address, StartBit, EndBit, Value) :
+ PciCf8BitFieldWrite16 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
+ writes the result back to the bit field in the 16-bit port.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldOr16 (Address, StartBit, EndBit, OrData) :
+ PciCf8BitFieldOr16 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
+ AND, and writes the result back to the bit field in the 16-bit register.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldAnd16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAnd16 (Address, StartBit, EndBit, AndData) :
+ PciCf8BitFieldAnd16 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
+ bitwise OR, and writes the result back to the bit field in the
+ 16-bit port.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise OR between the read result and
+ the value specified by AndData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldAndThenOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData) :
+ PciCf8BitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads a 32-bit PCI configuration register.
+
+ Reads and returns the 32-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @return The read value from the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciRead32 (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRead32 (Address) :
+ PciCf8Read32 (Address);
+}
+
+/**
+ Writes a 32-bit PCI configuration register.
+
+ Writes the 32-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param Value The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciWrite32 (
+ IN UINTN Address,
+ IN UINT32 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWrite32 (Address, Value) :
+ PciCf8Write32 (Address, Value);
+}
+
+/**
+ Performs a bitwise OR of a 32-bit PCI configuration register with
+ a 32-bit value.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciOr32 (
+ IN UINTN Address,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressOr32 (Address, OrData) :
+ PciCf8Or32 (Address, OrData);
+}
+
+/**
+ Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
+ value.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciAnd32 (
+ IN UINTN Address,
+ IN UINT32 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAnd32 (Address, AndData) :
+ PciCf8And32 (Address, AndData);
+}
+
+/**
+ Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
+ value, followed a bitwise OR with another 32-bit value.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciAndThenOr32 (
+ IN UINTN Address,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAndThenOr32 (Address, AndData, OrData) :
+ PciCf8AndThenOr32 (Address, AndData, OrData);
+}
+
+/**
+ Reads a bit field of a PCI configuration register.
+
+ Reads the bit field in a 32-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Address The PCI configuration register to read.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+
+ @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldRead32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldRead32 (Address, StartBit, EndBit) :
+ PciCf8BitFieldRead32 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes a bit field to a PCI configuration register.
+
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 32-bit register is returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param Value The new value of the bit field.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldWrite32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldWrite32 (Address, StartBit, EndBit, Value) :
+ PciCf8BitFieldWrite32 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
+ writes the result back to the bit field in the 32-bit port.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldOr32 (Address, StartBit, EndBit, OrData) :
+ PciCf8BitFieldOr32 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
+ AND, and writes the result back to the bit field in the 32-bit register.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldAnd32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAnd32 (Address, StartBit, EndBit, AndData) :
+ PciCf8BitFieldAnd32 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
+ bitwise OR, and writes the result back to the bit field in the
+ 32-bit port.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise OR between the read result and
+ the value specified by AndData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldAndThenOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData) :
+ PciCf8BitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads a range of PCI configuration registers into a caller supplied buffer.
+
+ Reads the range of PCI configuration registers specified by StartAddress and
+ Size into the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be read. Size is
+ returned. When possible 32-bit PCI configuration read cycles are used to read
+ from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
+ and 16-bit PCI configuration read cycles may be used at the beginning and the
+ end of the range.
+
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param StartAddress The starting address that encodes the PCI Bus, Device,
+ Function and Register.
+ @param Size The size in bytes of the transfer.
+ @param Buffer The pointer to a buffer receiving the data read.
+
+ @return Size
+
+**/
+UINTN
+EFIAPI
+PciReadBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ OUT VOID *Buffer
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressReadBuffer (StartAddress, Size, Buffer) :
+ PciCf8ReadBuffer (StartAddress, Size, Buffer);
+}
+
+/**
+ Copies the data in a caller supplied buffer to a specified range of PCI
+ configuration space.
+
+ Writes the range of PCI configuration registers specified by StartAddress and
+ Size from the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be written. Size is
+ returned. When possible 32-bit PCI configuration write cycles are used to
+ write from StartAdress to StartAddress + Size. Due to alignment restrictions,
+ 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
+ and the end of the range.
+
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param StartAddress The starting address that encodes the PCI Bus, Device,
+ Function and Register.
+ @param Size The size in bytes of the transfer.
+ @param Buffer The pointer to a buffer containing the data to write.
+
+ @return Size written to StartAddress.
+
+**/
+UINTN
+EFIAPI
+PciWriteBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWriteBuffer (StartAddress, Size, Buffer) :
+ PciCf8WriteBuffer (StartAddress, Size, Buffer);
+}
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..b1d7552792
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
@@ -0,0 +1,1579 @@
+/** @file
+ ACPI Platform Driver
+
+ Copyright (c) 2017 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..a16c13466a
--- /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) 2017 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..8aa10a4a5b
--- /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) 2017 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..aa386ba149
--- /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) 2017 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..12e2feacb4
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c
@@ -0,0 +1,46 @@
+/** @file
+ ACPI WSMT table
+
+ Copyright (c) 2017 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..dd9cc80e42
--- /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 - 2010, 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..c2d82e7324
--- /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 - 2010 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..19ff5209d2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c
@@ -0,0 +1,417 @@
+/** @file
+ Graphics Output Protocol functions for the QEMU video controller.
+
+ Copyright (c) 2007 - 2018 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..fbf40e9eaf
--- /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 - 2010 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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
new file mode 100644
index 0000000000..b57bacdda4
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
@@ -0,0 +1,622 @@
+/** @file
+ This contains the installation function for the driver.
+
+ Copyright (c) 2005 - 2018 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "8259.h"
+
+//
+// Global for the Legacy 8259 Protocol that is produced by this driver
+//
+EFI_LEGACY_8259_PROTOCOL mInterrupt8259 = {
+ Interrupt8259SetVectorBase,
+ Interrupt8259GetMask,
+ Interrupt8259SetMask,
+ Interrupt8259SetMode,
+ Interrupt8259GetVector,
+ Interrupt8259EnableIrq,
+ Interrupt8259DisableIrq,
+ Interrupt8259GetInterruptLine,
+ Interrupt8259EndOfInterrupt
+};
+
+//
+// Global for the handle that the Legacy 8259 Protocol is installed
+//
+EFI_HANDLE m8259Handle = NULL;
+
+UINT8 mMasterBase = 0xff;
+UINT8 mSlaveBase = 0xff;
+EFI_8259_MODE mMode = Efi8259ProtectedMode;
+UINT16 mProtectedModeMask = 0xffff;
+UINT16 mLegacyModeMask;
+UINT16 mProtectedModeEdgeLevel = 0x0000;
+UINT16 mLegacyModeEdgeLevel;
+
+//
+// Worker Functions
+//
+
+/**
+ Write to mask and edge/level triggered registers of master and slave 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));
+}
+
+/**
+ Read from mask and edge/level triggered registers of master and slave PICs.
+
+ @param[out] Mask low byte for master PIC mask register,
+ high byte for slave PIC mask register.
+ @param[out] EdgeLevel low byte for master PIC edge/level triggered register,
+ high byte for slave PIC edge/level triggered register.
+
+**/
+VOID
+Interrupt8259ReadMask (
+ OUT UINT16 *Mask,
+ OUT UINT16 *EdgeLevel
+ )
+{
+ UINT16 MasterValue;
+ UINT16 SlaveValue;
+
+ if (Mask != NULL) {
+ MasterValue = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
+ SlaveValue = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
+
+ *Mask = (UINT16) (MasterValue | (SlaveValue << 8));
+ }
+
+ if (EdgeLevel != NULL) {
+ MasterValue = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER);
+ SlaveValue = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE);
+
+ *EdgeLevel = (UINT16) (MasterValue | (SlaveValue << 8));
+ }
+}
+
+//
+// Legacy 8259 Protocol Interface Functions
+//
+
+/**
+ Sets the base address for the 8259 master and slave PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
+ @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing to the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetVectorBase (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT8 MasterBase,
+ IN UINT8 SlaveBase
+ )
+{
+ UINT8 Mask;
+ EFI_TPL OriginalTpl;
+
+ OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+ //
+ // Set vector base for slave PIC
+ //
+ if (SlaveBase != mSlaveBase) {
+ mSlaveBase = SlaveBase;
+
+ //
+ // Initialization sequence is needed for setting vector base.
+ //
+
+ //
+ // Preserve interrtup mask register before initialization sequence
+ // because it will be cleared during initialization
+ //
+ Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
+
+ //
+ // ICW1: cascade mode, ICW4 write required
+ //
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, 0x11);
+
+ //
+ // ICW2: new vector base (must be multiple of 8)
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, mSlaveBase);
+
+ //
+ // ICW3: slave indentification code must be 2
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x02);
+
+ //
+ // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x01);
+
+ //
+ // Restore interrupt mask register
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, Mask);
+ }
+
+ //
+ // Set vector base for master PIC
+ //
+ if (MasterBase != mMasterBase) {
+ mMasterBase = MasterBase;
+
+ //
+ // Initialization sequence is needed for setting vector base.
+ //
+
+ //
+ // Preserve interrtup mask register before initialization sequence
+ // because it will be cleared during initialization
+ //
+ Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
+
+ //
+ // ICW1: cascade mode, ICW4 write required
+ //
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, 0x11);
+
+ //
+ // ICW2: new vector base (must be multiple of 8)
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, mMasterBase);
+
+ //
+ // ICW3: slave PIC is cascaded on IRQ2
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x04);
+
+ //
+ // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x01);
+
+ //
+ // Restore interrupt mask register
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, Mask);
+ }
+
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI);
+
+ gBS->RestoreTPL (OriginalTpl);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ OUT UINT16 *LegacyMask, OPTIONAL
+ OUT UINT16 *LegacyEdgeLevel, OPTIONAL
+ OUT UINT16 *ProtectedMask, OPTIONAL
+ OUT UINT16 *ProtectedEdgeLevel OPTIONAL
+ )
+{
+ if (LegacyMask != NULL) {
+ *LegacyMask = mLegacyModeMask;
+ }
+
+ if (LegacyEdgeLevel != NULL) {
+ *LegacyEdgeLevel = mLegacyModeEdgeLevel;
+ }
+
+ if (ProtectedMask != NULL) {
+ *ProtectedMask = mProtectedModeMask;
+ }
+
+ if (ProtectedEdgeLevel != NULL) {
+ *ProtectedEdgeLevel = mProtectedModeEdgeLevel;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT16 *LegacyMask, OPTIONAL
+ IN UINT16 *LegacyEdgeLevel, OPTIONAL
+ IN UINT16 *ProtectedMask, OPTIONAL
+ IN UINT16 *ProtectedEdgeLevel OPTIONAL
+ )
+{
+ if (LegacyMask != NULL) {
+ mLegacyModeMask = *LegacyMask;
+ }
+
+ if (LegacyEdgeLevel != NULL) {
+ mLegacyModeEdgeLevel = *LegacyEdgeLevel;
+ }
+
+ if (ProtectedMask != NULL) {
+ mProtectedModeMask = *ProtectedMask;
+ }
+
+ if (ProtectedEdgeLevel != NULL) {
+ mProtectedModeEdgeLevel = *ProtectedEdgeLevel;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Sets the mode of the PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Mode 16-bit real or 32-bit protected mode.
+ @param[in] Mask The value with which to set the interrupt mask.
+ @param[in] EdgeLevel The value with which to set the edge/level mask.
+
+ @retval EFI_SUCCESS The mode was set successfully.
+ @retval EFI_INVALID_PARAMETER The mode was not set.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMode (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_MODE Mode,
+ IN UINT16 *Mask, OPTIONAL
+ IN UINT16 *EdgeLevel OPTIONAL
+ )
+{
+ if (Mode == mMode) {
+ return EFI_SUCCESS;
+ }
+
+ if (Mode == Efi8259LegacyMode) {
+ //
+ // In Efi8259ProtectedMode, mask and edge/level trigger registers should
+ // be changed through this protocol, so we can track them in the
+ // corresponding module variables.
+ //
+ Interrupt8259ReadMask (&mProtectedModeMask, &mProtectedModeEdgeLevel);
+
+ if (Mask != NULL) {
+ //
+ // Update the Mask for the new mode
+ //
+ mLegacyModeMask = *Mask;
+ }
+
+ if (EdgeLevel != NULL) {
+ //
+ // Update the Edge/Level triggered mask for the new mode
+ //
+ mLegacyModeEdgeLevel = *EdgeLevel;
+ }
+
+ mMode = Mode;
+
+ //
+ // Write new legacy mode mask/trigger level
+ //
+ Interrupt8259WriteMask (mLegacyModeMask, mLegacyModeEdgeLevel);
+
+ return EFI_SUCCESS;
+ }
+
+ if (Mode == Efi8259ProtectedMode) {
+ //
+ // Save the legacy mode mask/trigger level
+ //
+ Interrupt8259ReadMask (&mLegacyModeMask, &mLegacyModeEdgeLevel);
+ //
+ // Always force Timer to be enabled after return from 16-bit code.
+ // This always insures that on next entry, timer is counting.
+ //
+ mLegacyModeMask &= 0xFFFE;
+
+ if (Mask != NULL) {
+ //
+ // Update the Mask for the new mode
+ //
+ mProtectedModeMask = *Mask;
+ }
+
+ if (EdgeLevel != NULL) {
+ //
+ // Update the Edge/Level triggered mask for the new mode
+ //
+ mProtectedModeEdgeLevel = *EdgeLevel;
+ }
+
+ mMode = Mode;
+
+ //
+ // Write new protected mode mask/trigger level
+ //
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ Translates the IRQ into a vector.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[out] Vector The vector that is assigned to the IRQ.
+
+ @retval EFI_SUCCESS The Vector that matches Irq was returned.
+ @retval EFI_INVALID_PARAMETER Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetVector (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ OUT UINT8 *Vector
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Irq <= Efi8259Irq7) {
+ *Vector = (UINT8) (mMasterBase + Irq);
+ } else {
+ *Vector = (UINT8) (mSlaveBase + (Irq - Efi8259Irq8));
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Enables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
+
+ @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EnableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ IN BOOLEAN LevelTriggered
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ mProtectedModeMask = (UINT16) (mProtectedModeMask & ~(1 << Irq));
+ if (LevelTriggered) {
+ mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel | (1 << Irq));
+ } else {
+ mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq));
+ }
+
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Disables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259DisableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ mProtectedModeMask = (UINT16) (mProtectedModeMask | (1 << Irq));
+
+ mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq));
+
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Reads the PCI configuration space to get the interrupt number that is assigned to the card.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] PciHandle PCI function for which to return the vector.
+ @param[out] Vector IRQ number that corresponds to the interrupt line.
+
+ @retval EFI_SUCCESS The interrupt line value was read successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetInterruptLine (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT UINT8 *Vector
+ )
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 InterruptLine;
+ EFI_STATUS Status;
+
+ Status = gBS->HandleProtocol (
+ PciHandle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ PCI_INT_LINE_OFFSET,
+ 1,
+ &InterruptLine
+ );
+ //
+ // Interrupt line is same location for standard PCI cards, standard
+ // bridge and CardBus bridge.
+ //
+ *Vector = InterruptLine;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Issues the End of Interrupt (EOI) commands to PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq The interrupt for which to issue the EOI command.
+
+ @retval EFI_SUCCESS The EOI command was issued.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EndOfInterrupt (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Irq >= Efi8259Irq8) {
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);
+ }
+
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Driver Entry point.
+
+ @param[in] ImageHandle ImageHandle of the loaded driver.
+ @param[in] SystemTable Pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS One or more of the drivers returned a success code.
+ @retval !EFI_SUCCESS Error installing Legacy 8259 Protocol.
+
+**/
+EFI_STATUS
+EFIAPI
+Install8259 (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_8259_IRQ Irq;
+
+ //
+ // Initialze mask values from PCDs
+ //
+ mLegacyModeMask = PcdGet16 (Pcd8259LegacyModeMask);
+ mLegacyModeEdgeLevel = PcdGet16 (Pcd8259LegacyModeEdgeLevel);
+
+ //
+ // Clear all pending interrupt
+ //
+ for (Irq = Efi8259Irq0; Irq <= Efi8259Irq15; Irq++) {
+ Interrupt8259EndOfInterrupt (&mInterrupt8259, Irq);
+ }
+
+ //
+ // Set the 8259 Master base to 0x68 and the 8259 Slave base to 0x70
+ //
+ Status = Interrupt8259SetVectorBase (&mInterrupt8259, PROTECTED_MODE_BASE_VECTOR_MASTER, PROTECTED_MODE_BASE_VECTOR_SLAVE);
+
+ //
+ // Set all 8259 interrupts to edge triggered and disabled
+ //
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ //
+ // Install 8259 Protocol onto a new handle
+ //
+ Status = gBS->InstallProtocolInterface (
+ &m8259Handle,
+ &gEfiLegacy8259ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mInterrupt8259
+ );
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h
new file mode 100644
index 0000000000..3bf31067fa
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h
@@ -0,0 +1,68 @@
+/** @file
+ Header file of OVMF instance of PciHostBridgeLib.
+
+ Copyright (c) 2016 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/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
new file mode 100644
index 0000000000..8c6de3dca6
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -0,0 +1,50 @@
+## @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/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ PciLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h
new file mode 100644
index 0000000000..1fb031b752
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h
@@ -0,0 +1,156 @@
+/** @file
+ Platform BDS customizations include file.
+
+ Copyright (c) 2006 - 2017 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
+ );
+
+#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644
index 0000000000..55da35e87d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -0,0 +1,69 @@
+## @file
+# Platform BDS customizations library.
+#
+# Copyright (c) 2007 - 2018 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/SimicsOpenBoardPkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ UefiBootManagerLib
+ BootLogoLib
+ DevicePathLib
+ PciLib
+ NvVarsFileLib
+ LoadLinuxLib
+ UefiLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent
+ gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+ gSimicsX58PkgTokenSpaceGuid.PcdShellFile
+
+[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/Overrides/MdeModulePkg/Logo/Logo.bmp b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/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/Overrides/MdeModulePkg/Logo/Logo.idf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
new file mode 100644
index 0000000000..1f79332020
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
@@ -0,0 +1,10 @@
+// /** @file
+// Platform Logo image definition file.
+//
+// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#image IMG_LOGO Logo.bmp
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
new file mode 100644
index 0000000000..3380f3c1d5
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
@@ -0,0 +1,28 @@
+## @file
+# The default logo bitmap picture shown on setup screen, which is corresponding to gEfiDefaultBmpLogoGuid.
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Logo
+ MODULE_UNI_FILE = Logo.uni
+ FILE_GUID = 7BB28B99-61BB-11D5-9A5D-0090273FC14D
+ 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 ARM AARCH64
+#
+
+[Binaries]
+ BIN|Logo.bmp|*
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ LogoExtra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
new file mode 100644
index 0000000000..9d1bbaffa9
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
@@ -0,0 +1,16 @@
+// /** @file
+// The default logo bitmap picture shown on setup screen, which is corresponding to gEfiDefaultBmpLogoGuid.
+//
+// This module provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid.
+//
+// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid."
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf
new file mode 100644
index 0000000000..01102b138f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf
@@ -0,0 +1,55 @@
+## @file
+# The default logo bitmap picture shown on setup screen.
+#
+# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LogoDxe
+ MODULE_UNI_FILE = LogoDxe.uni
+ FILE_GUID = F74D20EE-37E7-48FC-97F7-9B1047749C69
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeLogo
+#
+# This flag specifies whether HII resource section is generated into PE image.
+#
+ UEFI_HII_RESOURCE_SECTION = TRUE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ Logo.bmp
+ Logo.c
+ Logo.idf
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ DebugLib
+
+[Protocols]
+ gEfiHiiDatabaseProtocolGuid ## CONSUMES
+ gEfiHiiImageExProtocolGuid ## CONSUMES
+ gEfiHiiPackageListProtocolGuid ## PRODUCES CONSUMES
+ gEdkiiPlatformLogoProtocolGuid ## PRODUCES
+
+[Depex]
+ gEfiHiiDatabaseProtocolGuid AND
+ gEfiHiiImageExProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ LogoDxeExtra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni
new file mode 100644
index 0000000000..9635701b60
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni
@@ -0,0 +1,16 @@
+// /** @file
+// The default logo bitmap picture shown on setup screen.
+//
+// This module provides the default logo bitmap picture shown on setup screen, through EDKII Platform Logo protocol.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides the default logo bitmap picture shown on setup screen."
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module provides the default logo bitmap picture shown on setup screen, through EDKII Platform Logo protocol."
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni
new file mode 100644
index 0000000000..c6ea34b81d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Logo Localized Strings and Content
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Logo Image File"
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni
new file mode 100644
index 0000000000..041179fb75
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Logo Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Logo Image File"
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
new file mode 100644
index 0000000000..e5ca95e20e
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
@@ -0,0 +1,40 @@
+## @file
+# An instance of the PCI Library that is based on both the PCI CF8 Library and
+# the PCI Express Library.
+#
+# This PciLib instance caches the SimicsX58 platform type (X58-ICH10) in
+# its entry point function, then delegates function calls to one of the
+# PciCf8Lib or PciExpressLib "backends" as appropriate.
+#
+# Copyright (C) 2016, Red Hat, Inc.
+# Copyright (c) 2007 - 2014 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxePciLibX58Ich10
+ FILE_GUID = FC214B5D-B5B5-4E54-9B28-5E94532E5E2A
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PciLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION
+ CONSTRUCTOR = InitializeConfigAccessMethod
+
+# VALID_ARCHITECTURES = IA32 X64
+
+[Sources]
+ PciLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ PcdLib
+ PciCf8Lib
+ PciExpressLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
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..2deb2a88eb
--- /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) 2017 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..b4b52b6622
--- /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) 2017 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..8370559016
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
@@ -0,0 +1,73 @@
+## @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/SimicsOpenBoardPkg.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
+ gSimicsX58PkgTokenSpaceGuid.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..cb2a60d827
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm
@@ -0,0 +1,281 @@
+;------------------------------------------------------------------------------
+; @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
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
new file mode 100644
index 0000000000..a9673f9c87
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
@@ -0,0 +1,218 @@
+/** @file
+ Driver implementing the Tiano Legacy 8259 Protocol
+
+Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _8259_H__
+#define _8259_H__
+
+#include <Protocol/Legacy8259.h>
+#include <Protocol/PciIo.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+// 8259 Hardware definitions
+
+#define LEGACY_MODE_BASE_VECTOR_MASTER 0x08
+#define LEGACY_MODE_BASE_VECTOR_SLAVE 0x70
+
+#define PROTECTED_MODE_BASE_VECTOR_MASTER 0x68
+#define PROTECTED_MODE_BASE_VECTOR_SLAVE 0x70
+
+#define LEGACY_8259_CONTROL_REGISTER_MASTER 0x20
+#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
+#define LEGACY_8259_CONTROL_REGISTER_SLAVE 0xA0
+#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
+
+#define LEGACY_8259_EOI 0x20
+
+// Protocol Function Prototypes
+
+/**
+ Sets the base address for the 8259 master and slave PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
+ @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing to the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetVectorBase (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT8 MasterBase,
+ IN UINT8 SlaveBase
+ );
+
+/**
+ Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ OUT UINT16 *LegacyMask, OPTIONAL
+ OUT UINT16 *LegacyEdgeLevel, OPTIONAL
+ OUT UINT16 *ProtectedMask, OPTIONAL
+ OUT UINT16 *ProtectedEdgeLevel OPTIONAL
+ );
+
+/**
+ Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT16 *LegacyMask, OPTIONAL
+ IN UINT16 *LegacyEdgeLevel, OPTIONAL
+ IN UINT16 *ProtectedMask, OPTIONAL
+ IN UINT16 *ProtectedEdgeLevel OPTIONAL
+ );
+
+/**
+ Sets the mode of the PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Mode 16-bit real or 32-bit protected mode.
+ @param[in] Mask The value with which to set the interrupt mask.
+ @param[in] EdgeLevel The value with which to set the edge/level mask.
+
+ @retval EFI_SUCCESS The mode was set successfully.
+ @retval EFI_INVALID_PARAMETER The mode was not set.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMode (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_MODE Mode,
+ IN UINT16 *Mask, OPTIONAL
+ IN UINT16 *EdgeLevel OPTIONAL
+ );
+
+/**
+ Translates the IRQ into a vector.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[out] Vector The vector that is assigned to the IRQ.
+
+ @retval EFI_SUCCESS The Vector that matches Irq was returned.
+ @retval EFI_INVALID_PARAMETER Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetVector (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ OUT UINT8 *Vector
+ );
+
+/**
+ Enables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
+
+ @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EnableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ IN BOOLEAN LevelTriggered
+ );
+
+/**
+ Disables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259DisableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ );
+
+/**
+ Reads the PCI configuration space to get the interrupt number that is assigned to the card.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] PciHandle PCI function for which to return the vector.
+ @param[out] Vector IRQ number that corresponds to the interrupt line.
+
+ @retval EFI_SUCCESS The interrupt line value was read successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetInterruptLine (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT UINT8 *Vector
+ );
+
+/**
+ Issues the End of Interrupt (EOI) commands to PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq The interrupt for which to issue the EOI command.
+
+ @retval EFI_SUCCESS The EOI command was issued.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EndOfInterrupt (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ );
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
new file mode 100644
index 0000000000..e66b21c914
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
@@ -0,0 +1,46 @@
+## @file
+# 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
+#
+# Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Legacy8259
+ MODULE_UNI_FILE = Legacy8259.uni
+ FILE_GUID = 79CA4208-BBA1-4a9a-8456-E1E66A81484E
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = Install8259
+
+[Sources]
+ 8259.c
+ 8259.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ PcAtChipsetPkg/PcAtChipsetPkg.dec
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ DebugLib
+ UefiDriverEntryPoint
+ IoLib
+ PcdLib
+
+[Protocols]
+ gEfiLegacy8259ProtocolGuid ## PRODUCES
+ gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMES
+
+[Pcd]
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask ## CONSUMES
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel ## CONSUMES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ Legacy8259Extra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
new file mode 100644
index 0000000000..d035292419
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
@@ -0,0 +1,16 @@
+// /** @file
+// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
+//
+// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
+//
+// Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "8259 Interrupt Controller driver that provides Legacy 8259 protocol"
+
+#string STR_MODULE_DESCRIPTION #language en-US "8259 Interrupt Controller driver that provides Legacy 8259 protocol."
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
new file mode 100644
index 0000000000..ee43f6923c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Legacy8259 Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Legacy 8259 Interrupt Controller DXE Driver"
+
+
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
2019-08-09 22:46 ` [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform David Wei
2019-08-15 19:38 ` Nate DeSimone
@ 2019-08-15 22:52 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2 siblings, 0 replies; 37+ messages in thread
From: Nate DeSimone @ 2019-08-15 22:52 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
Hi David,
Here are my comments:
1. All of the copyright years need to be updated to 2019.
2. Please remove " Contributed-under: TianoCore Contribution Agreement 1.0" from your commit message as it is no longer needed.
3. Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib - This library is not an override. It is an alternate and separate implementation. MdeModulePkg does not even have a PciHostBridgeLib implementation other than a stub version. This implementation also appears very similar to the one in OvmfPkg. Please move this to SimicsOpenBoardPkg/Library.
4. Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib - This library is not an override. It is an alternate and separate implementation. MdeModulePkg does not even have a PlatformBootManagerLib implementation other than a stub version. This implementation also appears very similar to the one in OvmfPkg. Please move this to SimicsOpenBoardPkg/Library.
5. Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables - This override is just coding style fixes. Do not add this as an override. Submit a separate patch series for the style cleanup directly on MinPlatformPkg.
6. Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe - Why does this override exist? It does not change anything.
Other than that, looks good! Please send an updated patch.
Thanks,
Nate
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 9, 2019 3:47 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-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
Overrides/MdeModulePkg/Library/PciHostBridgeLib - it is platform related. should be Customized
Overrides/MdeModulePkg/Logo - the Logo image is Customized
Overrides/MdePkg/Library/BasePciLibCf8 - use the functions specific for SIMICS
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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
.../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++
.../Library/PlatformBootManagerLib/BdsPlatform.c | 1553 +++++++++++++++++++
.../Library/PlatformBootManagerLib/PlatformData.c | 35 +
.../Overrides/MdeModulePkg/Logo/Logo.c | 154 ++
.../MdePkg/Library/BasePciLibCf8/PciLib.c | 1221 +++++++++++++++
.../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 | 417 ++++++
.../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++
.../8259InterruptControllerDxe/8259.c | 622 ++++++++
.../Library/PciHostBridgeLib/PciHostBridge.h | 68 +
.../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 50 +
.../Library/PlatformBootManagerLib/BdsPlatform.h | 156 ++
.../PlatformBootManagerLib.inf | 69 +
.../Overrides/MdeModulePkg/Logo/Logo.bmp | Bin 0 -> 141078 bytes
.../Overrides/MdeModulePkg/Logo/Logo.idf | 10 +
.../Overrides/MdeModulePkg/Logo/Logo.inf | 28 +
.../Overrides/MdeModulePkg/Logo/Logo.uni | 16 +
.../Overrides/MdeModulePkg/Logo/LogoDxe.inf | 55 +
.../Overrides/MdeModulePkg/Logo/LogoDxe.uni | 16 +
| 14 +
| 14 +
.../Library/BasePciLibCf8/DxePciLibX58Ich10.inf | 40 +
.../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 +
.../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++
.../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++
.../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 73 +
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 281 ++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++
.../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 +
.../8259InterruptControllerDxe/8259.h | 218 +++
.../8259InterruptControllerDxe/8259.inf | 46 +
.../8259InterruptControllerDxe/Legacy8259.uni | 16 +
| 14 +
41 files changed, 11062 insertions(+)
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.bmp
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
create mode 100644 Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
new file mode 100644
index 0000000000..2aaa4b3e90
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.c
@@ -0,0 +1,419 @@
+/** @file
+ OVMF'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 <IndustryStandard/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/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c
new file mode 100644
index 0000000000..0b66862e46
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -0,0 +1,1553 @@
+/** @file
+ Platform BDS customizations.
+
+ Copyright (c) 2004 - 2018 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
+ //
+ BootLogoEnableLogo();
+
+ 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/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformData.c
new file mode 100644
index 0000000000..5f1b16dd56
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/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 - 2017 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/Overrides/MdeModulePkg/Logo/Logo.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
new file mode 100644
index 0000000000..d4a75ad140
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
@@ -0,0 +1,154 @@
+/** @file
+ Logo DXE Driver, install Edkii Platform Logo protocol.
+
+ Copyright (c) 2016 - 2017 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/HiiImageEx.h>
+#include <Protocol/PlatformLogo.h>
+#include <Protocol/HiiPackageList.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+typedef struct {
+ EFI_IMAGE_ID ImageId;
+ EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE Attribute;
+ INTN OffsetX;
+ INTN OffsetY;
+} LOGO_ENTRY;
+
+EFI_HII_IMAGE_EX_PROTOCOL *mHiiImageEx;
+EFI_HII_HANDLE mHiiHandle;
+LOGO_ENTRY mLogos[] = {
+ {
+ IMAGE_TOKEN (IMG_LOGO),
+ EdkiiPlatformLogoDisplayAttributeCenter,
+ 0,
+ 0
+ }
+};
+
+/**
+ Load a platform logo image and return its data and attributes.
+
+ @param This The pointer to this protocol instance.
+ @param Instance The visible image instance is found.
+ @param Image Points to the image.
+ @param Attribute The display attributes of the image returned.
+ @param OffsetX The X offset of the image regarding the Attribute.
+ @param OffsetY The Y offset of the image regarding the Attribute.
+
+ @retval EFI_SUCCESS The image was fetched successfully.
+ @retval EFI_NOT_FOUND The specified image could not be found.
+**/
+EFI_STATUS
+EFIAPI
+GetImage (
+ IN EDKII_PLATFORM_LOGO_PROTOCOL *This,
+ IN OUT UINT32 *Instance,
+ OUT EFI_IMAGE_INPUT *Image,
+ OUT EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE *Attribute,
+ OUT INTN *OffsetX,
+ OUT INTN *OffsetY
+ )
+{
+ UINT32 Current;
+ if (Instance == NULL || Image == NULL ||
+ Attribute == NULL || OffsetX == NULL || OffsetY == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Current = *Instance;
+ if (Current >= ARRAY_SIZE (mLogos)) {
+ return EFI_NOT_FOUND;
+ }
+
+ (*Instance)++;
+ *Attribute = mLogos[Current].Attribute;
+ *OffsetX = mLogos[Current].OffsetX;
+ *OffsetY = mLogos[Current].OffsetY;
+ return mHiiImageEx->GetImageEx (mHiiImageEx, mHiiHandle, mLogos[Current].ImageId, Image);
+}
+
+EDKII_PLATFORM_LOGO_PROTOCOL mPlatformLogo = {
+ GetImage
+};
+
+/**
+ Entrypoint of this module.
+
+ This function is the entrypoint of this module. It installs the Edkii
+ Platform Logo protocol.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeLogo (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_PACKAGE_LIST_HEADER *PackageList;
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
+ EFI_HANDLE Handle;
+
+ Status = gBS->LocateProtocol (
+ &gEfiHiiDatabaseProtocolGuid,
+ NULL,
+ (VOID **) &HiiDatabase
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (
+ &gEfiHiiImageExProtocolGuid,
+ NULL,
+ (VOID **) &mHiiImageEx
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Retrieve HII package list from ImageHandle
+ //
+ Status = gBS->OpenProtocol (
+ ImageHandle,
+ &gEfiHiiPackageListProtocolGuid,
+ (VOID **) &PackageList,
+ ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "HII Image Package with logo not found in PE/COFF resource section\n"));
+ return Status;
+ }
+
+ //
+ // Publish HII package list to HII Database.
+ //
+ Status = HiiDatabase->NewPackageList (
+ HiiDatabase,
+ PackageList,
+ NULL,
+ &mHiiHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEdkiiPlatformLogoProtocolGuid, &mPlatformLogo,
+ NULL
+ );
+ }
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c
new file mode 100644
index 0000000000..7544117a03
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/PciLib.c
@@ -0,0 +1,1221 @@
+/** @file
+ PCI Library functions that use
+ (a) I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles, layering
+ on top of one PCI CF8 Library instance; or
+ (b) PCI Library functions that use the 256 MB PCI Express MMIO window to
+ perform PCI Configuration cycles, layering on PCI Express Library.
+
+ The decision is made in the entry point function, based on the OVMF platform
+ type, and then adhered to during the lifetime of the client module.
+
+ Copyright (C) 2016, Red Hat, Inc.
+ Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+
+#include <IndustryStandard/X58Ich10.h>
+
+#include <Library/PciLib.h>
+#include <Library/PciCf8Lib.h>
+#include <Library/PciExpressLib.h>
+#include <Library/PcdLib.h>
+
+STATIC BOOLEAN mRunningOnIch10;
+
+RETURN_STATUS
+EFIAPI
+InitializeConfigAccessMethod (
+ VOID
+ )
+{
+ mRunningOnIch10 = (PcdGet16 (PcdSimicsX58HostBridgePciDevId) ==
+ INTEL_ICH10_DEVICE_ID);
+ return RETURN_SUCCESS;
+}
+
+/**
+ Registers a PCI device so PCI configuration registers may be accessed after
+ SetVirtualAddressMap().
+
+ Registers the PCI device specified by Address so all the PCI configuration registers
+ associated with that PCI device may be accessed after SetVirtualAddressMap() is called.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @retval RETURN_SUCCESS The PCI device was registered for runtime access.
+ @retval RETURN_UNSUPPORTED An attempt was made to call this function
+ after ExitBootServices().
+ @retval RETURN_UNSUPPORTED The resources required to access the PCI device
+ at runtime could not be mapped.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough resources available to
+ complete the registration.
+
+**/
+RETURN_STATUS
+EFIAPI
+PciRegisterForRuntimeAccess (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRegisterForRuntimeAccess (Address) :
+ PciCf8RegisterForRuntimeAccess (Address);
+}
+
+/**
+ Reads an 8-bit PCI configuration register.
+
+ Reads and returns the 8-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @return The read value from the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciRead8 (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRead8 (Address) :
+ PciCf8Read8 (Address);
+}
+
+/**
+ Writes an 8-bit PCI configuration register.
+
+ Writes the 8-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param Value The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciWrite8 (
+ IN UINTN Address,
+ IN UINT8 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWrite8 (Address, Value) :
+ PciCf8Write8 (Address, Value);
+}
+
+/**
+ Performs a bitwise OR of an 8-bit PCI configuration register with
+ an 8-bit value.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciOr8 (
+ IN UINTN Address,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressOr8 (Address, OrData) :
+ PciCf8Or8 (Address, OrData);
+}
+
+/**
+ Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
+ value.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciAnd8 (
+ IN UINTN Address,
+ IN UINT8 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAnd8 (Address, AndData) :
+ PciCf8And8 (Address, AndData);
+}
+
+/**
+ Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
+ value, followed a bitwise OR with another 8-bit value.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciAndThenOr8 (
+ IN UINTN Address,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAndThenOr8 (Address, AndData, OrData) :
+ PciCf8AndThenOr8 (Address, AndData, OrData);
+}
+
+/**
+ Reads a bit field of a PCI configuration register.
+
+ Reads the bit field in an 8-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Address The PCI configuration register to read.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+
+ @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldRead8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldRead8 (Address, StartBit, EndBit) :
+ PciCf8BitFieldRead8 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes a bit field to a PCI configuration register.
+
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 8-bit register is returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param Value The new value of the bit field.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldWrite8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldWrite8 (Address, StartBit, EndBit, Value) :
+ PciCf8BitFieldWrite8 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
+ writes the result back to the bit field in the 8-bit port.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldOr8 (Address, StartBit, EndBit, OrData) :
+ PciCf8BitFieldOr8 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
+ AND, and writes the result back to the bit field in the 8-bit register.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldAnd8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAnd8 (Address, StartBit, EndBit, AndData) :
+ PciCf8BitFieldAnd8 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
+ bitwise OR, and writes the result back to the bit field in the
+ 8-bit port.
+
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise OR between the read result and
+ the value specified by AndData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..7.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..7.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT8
+EFIAPI
+PciBitFieldAndThenOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData) :
+ PciCf8BitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads a 16-bit PCI configuration register.
+
+ Reads and returns the 16-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @return The read value from the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciRead16 (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRead16 (Address) :
+ PciCf8Read16 (Address);
+}
+
+/**
+ Writes a 16-bit PCI configuration register.
+
+ Writes the 16-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param Value The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciWrite16 (
+ IN UINTN Address,
+ IN UINT16 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWrite16 (Address, Value) :
+ PciCf8Write16 (Address, Value);
+}
+
+/**
+ Performs a bitwise OR of a 16-bit PCI configuration register with
+ a 16-bit value.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciOr16 (
+ IN UINTN Address,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressOr16 (Address, OrData) :
+ PciCf8Or16 (Address, OrData);
+}
+
+/**
+ Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
+ value.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciAnd16 (
+ IN UINTN Address,
+ IN UINT16 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAnd16 (Address, AndData) :
+ PciCf8And16 (Address, AndData);
+}
+
+/**
+ Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
+ value, followed a bitwise OR with another 16-bit value.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciAndThenOr16 (
+ IN UINTN Address,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAndThenOr16 (Address, AndData, OrData) :
+ PciCf8AndThenOr16 (Address, AndData, OrData);
+}
+
+/**
+ Reads a bit field of a PCI configuration register.
+
+ Reads the bit field in a 16-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Address The PCI configuration register to read.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+
+ @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldRead16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldRead16 (Address, StartBit, EndBit) :
+ PciCf8BitFieldRead16 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes a bit field to a PCI configuration register.
+
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 16-bit register is returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param Value The new value of the bit field.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldWrite16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldWrite16 (Address, StartBit, EndBit, Value) :
+ PciCf8BitFieldWrite16 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
+ writes the result back to the bit field in the 16-bit port.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldOr16 (Address, StartBit, EndBit, OrData) :
+ PciCf8BitFieldOr16 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
+ AND, and writes the result back to the bit field in the 16-bit register.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldAnd16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAnd16 (Address, StartBit, EndBit, AndData) :
+ PciCf8BitFieldAnd16 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
+ bitwise OR, and writes the result back to the bit field in the
+ 16-bit port.
+
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise OR between the read result and
+ the value specified by AndData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..15.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..15.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT16
+EFIAPI
+PciBitFieldAndThenOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData) :
+ PciCf8BitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads a 32-bit PCI configuration register.
+
+ Reads and returns the 32-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+
+ @return The read value from the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciRead32 (
+ IN UINTN Address
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressRead32 (Address) :
+ PciCf8Read32 (Address);
+}
+
+/**
+ Writes a 32-bit PCI configuration register.
+
+ Writes the 32-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param Value The value to write.
+
+ @return The value written to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciWrite32 (
+ IN UINTN Address,
+ IN UINT32 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWrite32 (Address, Value) :
+ PciCf8Write32 (Address, Value);
+}
+
+/**
+ Performs a bitwise OR of a 32-bit PCI configuration register with
+ a 32-bit value.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciOr32 (
+ IN UINTN Address,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressOr32 (Address, OrData) :
+ PciCf8Or32 (Address, OrData);
+}
+
+/**
+ Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
+ value.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciAnd32 (
+ IN UINTN Address,
+ IN UINT32 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAnd32 (Address, AndData) :
+ PciCf8And32 (Address, AndData);
+}
+
+/**
+ Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
+ value, followed a bitwise OR with another 32-bit value.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param Address The address that encodes the PCI Bus, Device, Function and
+ Register.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciAndThenOr32 (
+ IN UINTN Address,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressAndThenOr32 (Address, AndData, OrData) :
+ PciCf8AndThenOr32 (Address, AndData, OrData);
+}
+
+/**
+ Reads a bit field of a PCI configuration register.
+
+ Reads the bit field in a 32-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param Address The PCI configuration register to read.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+
+ @return The value of the bit field read from the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldRead32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldRead32 (Address, StartBit, EndBit) :
+ PciCf8BitFieldRead32 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes a bit field to a PCI configuration register.
+
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 32-bit register is returned.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If Value is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param Value The new value of the bit field.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldWrite32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 Value
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldWrite32 (Address, StartBit, EndBit, Value) :
+ PciCf8BitFieldWrite32 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
+ writes the result back to the bit field in the 32-bit port.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param OrData The value to OR with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldOr32 (Address, StartBit, EndBit, OrData) :
+ PciCf8BitFieldOr32 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
+ AND, and writes the result back to the bit field in the 32-bit register.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param AndData The value to AND with the PCI configuration register.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldAnd32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAnd32 (Address, StartBit, EndBit, AndData) :
+ PciCf8BitFieldAnd32 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
+ bitwise OR, and writes the result back to the bit field in the
+ 32-bit port.
+
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise OR between the read result and
+ the value specified by AndData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+ If AndData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+ If OrData is larger than the bitmask value range specified by StartBit and EndBit, then ASSERT().
+
+ @param Address The PCI configuration register to write.
+ @param StartBit The ordinal of the least significant bit in the bit field.
+ Range 0..31.
+ @param EndBit The ordinal of the most significant bit in the bit field.
+ Range 0..31.
+ @param AndData The value to AND with the PCI configuration register.
+ @param OrData The value to OR with the result of the AND operation.
+
+ @return The value written back to the PCI configuration register.
+
+**/
+UINT32
+EFIAPI
+PciBitFieldAndThenOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData) :
+ PciCf8BitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads a range of PCI configuration registers into a caller supplied buffer.
+
+ Reads the range of PCI configuration registers specified by StartAddress and
+ Size into the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be read. Size is
+ returned. When possible 32-bit PCI configuration read cycles are used to read
+ from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
+ and 16-bit PCI configuration read cycles may be used at the beginning and the
+ end of the range.
+
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param StartAddress The starting address that encodes the PCI Bus, Device,
+ Function and Register.
+ @param Size The size in bytes of the transfer.
+ @param Buffer The pointer to a buffer receiving the data read.
+
+ @return Size
+
+**/
+UINTN
+EFIAPI
+PciReadBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ OUT VOID *Buffer
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressReadBuffer (StartAddress, Size, Buffer) :
+ PciCf8ReadBuffer (StartAddress, Size, Buffer);
+}
+
+/**
+ Copies the data in a caller supplied buffer to a specified range of PCI
+ configuration space.
+
+ Writes the range of PCI configuration registers specified by StartAddress and
+ Size from the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be written. Size is
+ returned. When possible 32-bit PCI configuration write cycles are used to
+ write from StartAdress to StartAddress + Size. Due to alignment restrictions,
+ 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
+ and the end of the range.
+
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param StartAddress The starting address that encodes the PCI Bus, Device,
+ Function and Register.
+ @param Size The size in bytes of the transfer.
+ @param Buffer The pointer to a buffer containing the data to write.
+
+ @return Size written to StartAddress.
+
+**/
+UINTN
+EFIAPI
+PciWriteBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ return mRunningOnIch10 ?
+ PciExpressWriteBuffer (StartAddress, Size, Buffer) :
+ PciCf8WriteBuffer (StartAddress, Size, Buffer);
+}
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..b1d7552792
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.c
@@ -0,0 +1,1579 @@
+/** @file
+ ACPI Platform Driver
+
+ Copyright (c) 2017 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..a16c13466a
--- /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) 2017 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..8aa10a4a5b
--- /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) 2017 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..aa386ba149
--- /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) 2017 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..12e2feacb4
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTables/Wsmt/Wsmt.c
@@ -0,0 +1,46 @@
+/** @file
+ ACPI WSMT table
+
+ Copyright (c) 2017 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..dd9cc80e42
--- /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 - 2010, 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..c2d82e7324
--- /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 - 2010 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..19ff5209d2
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.c
@@ -0,0 +1,417 @@
+/** @file
+ Graphics Output Protocol functions for the QEMU video controller.
+
+ Copyright (c) 2007 - 2018 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..fbf40e9eaf
--- /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 - 2010 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/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
new file mode 100644
index 0000000000..b57bacdda4
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.c
@@ -0,0 +1,622 @@
+/** @file
+ This contains the installation function for the driver.
+
+ Copyright (c) 2005 - 2018 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include "8259.h"
+
+//
+// Global for the Legacy 8259 Protocol that is produced by this driver
+//
+EFI_LEGACY_8259_PROTOCOL mInterrupt8259 = {
+ Interrupt8259SetVectorBase,
+ Interrupt8259GetMask,
+ Interrupt8259SetMask,
+ Interrupt8259SetMode,
+ Interrupt8259GetVector,
+ Interrupt8259EnableIrq,
+ Interrupt8259DisableIrq,
+ Interrupt8259GetInterruptLine,
+ Interrupt8259EndOfInterrupt
+};
+
+//
+// Global for the handle that the Legacy 8259 Protocol is installed
+//
+EFI_HANDLE m8259Handle = NULL;
+
+UINT8 mMasterBase = 0xff;
+UINT8 mSlaveBase = 0xff;
+EFI_8259_MODE mMode = Efi8259ProtectedMode;
+UINT16 mProtectedModeMask = 0xffff;
+UINT16 mLegacyModeMask;
+UINT16 mProtectedModeEdgeLevel = 0x0000;
+UINT16 mLegacyModeEdgeLevel;
+
+//
+// Worker Functions
+//
+
+/**
+ Write to mask and edge/level triggered registers of master and slave 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));
+}
+
+/**
+ Read from mask and edge/level triggered registers of master and slave PICs.
+
+ @param[out] Mask low byte for master PIC mask register,
+ high byte for slave PIC mask register.
+ @param[out] EdgeLevel low byte for master PIC edge/level triggered register,
+ high byte for slave PIC edge/level triggered register.
+
+**/
+VOID
+Interrupt8259ReadMask (
+ OUT UINT16 *Mask,
+ OUT UINT16 *EdgeLevel
+ )
+{
+ UINT16 MasterValue;
+ UINT16 SlaveValue;
+
+ if (Mask != NULL) {
+ MasterValue = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
+ SlaveValue = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
+
+ *Mask = (UINT16) (MasterValue | (SlaveValue << 8));
+ }
+
+ if (EdgeLevel != NULL) {
+ MasterValue = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER);
+ SlaveValue = IoRead8 (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE);
+
+ *EdgeLevel = (UINT16) (MasterValue | (SlaveValue << 8));
+ }
+}
+
+//
+// Legacy 8259 Protocol Interface Functions
+//
+
+/**
+ Sets the base address for the 8259 master and slave PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
+ @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing to the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetVectorBase (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT8 MasterBase,
+ IN UINT8 SlaveBase
+ )
+{
+ UINT8 Mask;
+ EFI_TPL OriginalTpl;
+
+ OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+ //
+ // Set vector base for slave PIC
+ //
+ if (SlaveBase != mSlaveBase) {
+ mSlaveBase = SlaveBase;
+
+ //
+ // Initialization sequence is needed for setting vector base.
+ //
+
+ //
+ // Preserve interrtup mask register before initialization sequence
+ // because it will be cleared during initialization
+ //
+ Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
+
+ //
+ // ICW1: cascade mode, ICW4 write required
+ //
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, 0x11);
+
+ //
+ // ICW2: new vector base (must be multiple of 8)
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, mSlaveBase);
+
+ //
+ // ICW3: slave indentification code must be 2
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x02);
+
+ //
+ // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x01);
+
+ //
+ // Restore interrupt mask register
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, Mask);
+ }
+
+ //
+ // Set vector base for master PIC
+ //
+ if (MasterBase != mMasterBase) {
+ mMasterBase = MasterBase;
+
+ //
+ // Initialization sequence is needed for setting vector base.
+ //
+
+ //
+ // Preserve interrtup mask register before initialization sequence
+ // because it will be cleared during initialization
+ //
+ Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
+
+ //
+ // ICW1: cascade mode, ICW4 write required
+ //
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, 0x11);
+
+ //
+ // ICW2: new vector base (must be multiple of 8)
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, mMasterBase);
+
+ //
+ // ICW3: slave PIC is cascaded on IRQ2
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x04);
+
+ //
+ // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x01);
+
+ //
+ // Restore interrupt mask register
+ //
+ IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, Mask);
+ }
+
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI);
+
+ gBS->RestoreTPL (OriginalTpl);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ OUT UINT16 *LegacyMask, OPTIONAL
+ OUT UINT16 *LegacyEdgeLevel, OPTIONAL
+ OUT UINT16 *ProtectedMask, OPTIONAL
+ OUT UINT16 *ProtectedEdgeLevel OPTIONAL
+ )
+{
+ if (LegacyMask != NULL) {
+ *LegacyMask = mLegacyModeMask;
+ }
+
+ if (LegacyEdgeLevel != NULL) {
+ *LegacyEdgeLevel = mLegacyModeEdgeLevel;
+ }
+
+ if (ProtectedMask != NULL) {
+ *ProtectedMask = mProtectedModeMask;
+ }
+
+ if (ProtectedEdgeLevel != NULL) {
+ *ProtectedEdgeLevel = mProtectedModeEdgeLevel;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT16 *LegacyMask, OPTIONAL
+ IN UINT16 *LegacyEdgeLevel, OPTIONAL
+ IN UINT16 *ProtectedMask, OPTIONAL
+ IN UINT16 *ProtectedEdgeLevel OPTIONAL
+ )
+{
+ if (LegacyMask != NULL) {
+ mLegacyModeMask = *LegacyMask;
+ }
+
+ if (LegacyEdgeLevel != NULL) {
+ mLegacyModeEdgeLevel = *LegacyEdgeLevel;
+ }
+
+ if (ProtectedMask != NULL) {
+ mProtectedModeMask = *ProtectedMask;
+ }
+
+ if (ProtectedEdgeLevel != NULL) {
+ mProtectedModeEdgeLevel = *ProtectedEdgeLevel;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Sets the mode of the PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Mode 16-bit real or 32-bit protected mode.
+ @param[in] Mask The value with which to set the interrupt mask.
+ @param[in] EdgeLevel The value with which to set the edge/level mask.
+
+ @retval EFI_SUCCESS The mode was set successfully.
+ @retval EFI_INVALID_PARAMETER The mode was not set.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMode (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_MODE Mode,
+ IN UINT16 *Mask, OPTIONAL
+ IN UINT16 *EdgeLevel OPTIONAL
+ )
+{
+ if (Mode == mMode) {
+ return EFI_SUCCESS;
+ }
+
+ if (Mode == Efi8259LegacyMode) {
+ //
+ // In Efi8259ProtectedMode, mask and edge/level trigger registers should
+ // be changed through this protocol, so we can track them in the
+ // corresponding module variables.
+ //
+ Interrupt8259ReadMask (&mProtectedModeMask, &mProtectedModeEdgeLevel);
+
+ if (Mask != NULL) {
+ //
+ // Update the Mask for the new mode
+ //
+ mLegacyModeMask = *Mask;
+ }
+
+ if (EdgeLevel != NULL) {
+ //
+ // Update the Edge/Level triggered mask for the new mode
+ //
+ mLegacyModeEdgeLevel = *EdgeLevel;
+ }
+
+ mMode = Mode;
+
+ //
+ // Write new legacy mode mask/trigger level
+ //
+ Interrupt8259WriteMask (mLegacyModeMask, mLegacyModeEdgeLevel);
+
+ return EFI_SUCCESS;
+ }
+
+ if (Mode == Efi8259ProtectedMode) {
+ //
+ // Save the legacy mode mask/trigger level
+ //
+ Interrupt8259ReadMask (&mLegacyModeMask, &mLegacyModeEdgeLevel);
+ //
+ // Always force Timer to be enabled after return from 16-bit code.
+ // This always insures that on next entry, timer is counting.
+ //
+ mLegacyModeMask &= 0xFFFE;
+
+ if (Mask != NULL) {
+ //
+ // Update the Mask for the new mode
+ //
+ mProtectedModeMask = *Mask;
+ }
+
+ if (EdgeLevel != NULL) {
+ //
+ // Update the Edge/Level triggered mask for the new mode
+ //
+ mProtectedModeEdgeLevel = *EdgeLevel;
+ }
+
+ mMode = Mode;
+
+ //
+ // Write new protected mode mask/trigger level
+ //
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ Translates the IRQ into a vector.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[out] Vector The vector that is assigned to the IRQ.
+
+ @retval EFI_SUCCESS The Vector that matches Irq was returned.
+ @retval EFI_INVALID_PARAMETER Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetVector (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ OUT UINT8 *Vector
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Irq <= Efi8259Irq7) {
+ *Vector = (UINT8) (mMasterBase + Irq);
+ } else {
+ *Vector = (UINT8) (mSlaveBase + (Irq - Efi8259Irq8));
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Enables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
+
+ @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EnableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ IN BOOLEAN LevelTriggered
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ mProtectedModeMask = (UINT16) (mProtectedModeMask & ~(1 << Irq));
+ if (LevelTriggered) {
+ mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel | (1 << Irq));
+ } else {
+ mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq));
+ }
+
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Disables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259DisableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ mProtectedModeMask = (UINT16) (mProtectedModeMask | (1 << Irq));
+
+ mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 << Irq));
+
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Reads the PCI configuration space to get the interrupt number that is assigned to the card.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] PciHandle PCI function for which to return the vector.
+ @param[out] Vector IRQ number that corresponds to the interrupt line.
+
+ @retval EFI_SUCCESS The interrupt line value was read successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetInterruptLine (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT UINT8 *Vector
+ )
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 InterruptLine;
+ EFI_STATUS Status;
+
+ Status = gBS->HandleProtocol (
+ PciHandle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ PCI_INT_LINE_OFFSET,
+ 1,
+ &InterruptLine
+ );
+ //
+ // Interrupt line is same location for standard PCI cards, standard
+ // bridge and CardBus bridge.
+ //
+ *Vector = InterruptLine;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Issues the End of Interrupt (EOI) commands to PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq The interrupt for which to issue the EOI command.
+
+ @retval EFI_SUCCESS The EOI command was issued.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EndOfInterrupt (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ )
+{
+ if ((UINT32)Irq > Efi8259Irq15) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Irq >= Efi8259Irq8) {
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);
+ }
+
+ IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, LEGACY_8259_EOI);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Driver Entry point.
+
+ @param[in] ImageHandle ImageHandle of the loaded driver.
+ @param[in] SystemTable Pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS One or more of the drivers returned a success code.
+ @retval !EFI_SUCCESS Error installing Legacy 8259 Protocol.
+
+**/
+EFI_STATUS
+EFIAPI
+Install8259 (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_8259_IRQ Irq;
+
+ //
+ // Initialze mask values from PCDs
+ //
+ mLegacyModeMask = PcdGet16 (Pcd8259LegacyModeMask);
+ mLegacyModeEdgeLevel = PcdGet16 (Pcd8259LegacyModeEdgeLevel);
+
+ //
+ // Clear all pending interrupt
+ //
+ for (Irq = Efi8259Irq0; Irq <= Efi8259Irq15; Irq++) {
+ Interrupt8259EndOfInterrupt (&mInterrupt8259, Irq);
+ }
+
+ //
+ // Set the 8259 Master base to 0x68 and the 8259 Slave base to 0x70
+ //
+ Status = Interrupt8259SetVectorBase (&mInterrupt8259, PROTECTED_MODE_BASE_VECTOR_MASTER, PROTECTED_MODE_BASE_VECTOR_SLAVE);
+
+ //
+ // Set all 8259 interrupts to edge triggered and disabled
+ //
+ Interrupt8259WriteMask (mProtectedModeMask, mProtectedModeEdgeLevel);
+
+ //
+ // Install 8259 Protocol onto a new handle
+ //
+ Status = gBS->InstallProtocolInterface (
+ &m8259Handle,
+ &gEfiLegacy8259ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mInterrupt8259
+ );
+ return Status;
+}
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h
new file mode 100644
index 0000000000..3bf31067fa
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridge.h
@@ -0,0 +1,68 @@
+/** @file
+ Header file of OVMF instance of PciHostBridgeLib.
+
+ Copyright (c) 2016 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/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
new file mode 100644
index 0000000000..8c6de3dca6
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
@@ -0,0 +1,50 @@
+## @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/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ PciLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase
+ gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base
+ gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h
new file mode 100644
index 0000000000..1fb031b752
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/BdsPlatform.h
@@ -0,0 +1,156 @@
+/** @file
+ Platform BDS customizations include file.
+
+ Copyright (c) 2006 - 2017 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
+ );
+
+#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644
index 0000000000..55da35e87d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -0,0 +1,69 @@
+## @file
+# Platform BDS customizations library.
+#
+# Copyright (c) 2007 - 2018 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/SimicsOpenBoardPkg.dec
+ OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ UefiBootManagerLib
+ BootLogoLib
+ DevicePathLib
+ PciLib
+ NvVarsFileLib
+ LoadLinuxLib
+ UefiLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent
+ gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+ gSimicsX58PkgTokenSpaceGuid.PcdShellFile
+
+[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/Overrides/MdeModulePkg/Logo/Logo.bmp b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/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/Overrides/MdeModulePkg/Logo/Logo.idf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
new file mode 100644
index 0000000000..1f79332020
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
@@ -0,0 +1,10 @@
+// /** @file
+// Platform Logo image definition file.
+//
+// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#image IMG_LOGO Logo.bmp
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
new file mode 100644
index 0000000000..3380f3c1d5
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
@@ -0,0 +1,28 @@
+## @file
+# The default logo bitmap picture shown on setup screen, which is corresponding to gEfiDefaultBmpLogoGuid.
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Logo
+ MODULE_UNI_FILE = Logo.uni
+ FILE_GUID = 7BB28B99-61BB-11D5-9A5D-0090273FC14D
+ 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 ARM AARCH64
+#
+
+[Binaries]
+ BIN|Logo.bmp|*
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ LogoExtra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
new file mode 100644
index 0000000000..9d1bbaffa9
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
@@ -0,0 +1,16 @@
+// /** @file
+// The default logo bitmap picture shown on setup screen, which is corresponding to gEfiDefaultBmpLogoGuid.
+//
+// This module provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid.
+//
+// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module provides the default logo bitmap picture shown on setup screen, which corresponds to gEfiDefaultBmpLogoGuid."
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf
new file mode 100644
index 0000000000..01102b138f
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.inf
@@ -0,0 +1,55 @@
+## @file
+# The default logo bitmap picture shown on setup screen.
+#
+# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = LogoDxe
+ MODULE_UNI_FILE = LogoDxe.uni
+ FILE_GUID = F74D20EE-37E7-48FC-97F7-9B1047749C69
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeLogo
+#
+# This flag specifies whether HII resource section is generated into PE image.
+#
+ UEFI_HII_RESOURCE_SECTION = TRUE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ Logo.bmp
+ Logo.c
+ Logo.idf
+
+[Packages]
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ DebugLib
+
+[Protocols]
+ gEfiHiiDatabaseProtocolGuid ## CONSUMES
+ gEfiHiiImageExProtocolGuid ## CONSUMES
+ gEfiHiiPackageListProtocolGuid ## PRODUCES CONSUMES
+ gEdkiiPlatformLogoProtocolGuid ## PRODUCES
+
+[Depex]
+ gEfiHiiDatabaseProtocolGuid AND
+ gEfiHiiImageExProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ LogoDxeExtra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni
new file mode 100644
index 0000000000..9635701b60
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.uni
@@ -0,0 +1,16 @@
+// /** @file
+// The default logo bitmap picture shown on setup screen.
+//
+// This module provides the default logo bitmap picture shown on setup screen, through EDKII Platform Logo protocol.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides the default logo bitmap picture shown on setup screen."
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module provides the default logo bitmap picture shown on setup screen, through EDKII Platform Logo protocol."
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni
new file mode 100644
index 0000000000..c6ea34b81d
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Logo Localized Strings and Content
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Logo Image File"
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni
new file mode 100644
index 0000000000..041179fb75
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Logo Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Logo Image File"
+
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
new file mode 100644
index 0000000000..e5ca95e20e
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58Ich10.inf
@@ -0,0 +1,40 @@
+## @file
+# An instance of the PCI Library that is based on both the PCI CF8 Library and
+# the PCI Express Library.
+#
+# This PciLib instance caches the SimicsX58 platform type (X58-ICH10) in
+# its entry point function, then delegates function calls to one of the
+# PciCf8Lib or PciExpressLib "backends" as appropriate.
+#
+# Copyright (C) 2016, Red Hat, Inc.
+# Copyright (c) 2007 - 2014 Intel Corporation. All rights reserved. <BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxePciLibX58Ich10
+ FILE_GUID = FC214B5D-B5B5-4E54-9B28-5E94532E5E2A
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PciLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION
+ CONSTRUCTOR = InitializeConfigAccessMethod
+
+# VALID_ARCHITECTURES = IA32 X64
+
+[Sources]
+ PciLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ PcdLib
+ PciCf8Lib
+ PciExpressLib
+
+[Pcd]
+ gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
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..2deb2a88eb
--- /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) 2017 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..b4b52b6622
--- /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) 2017 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..8370559016
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
@@ -0,0 +1,73 @@
+## @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/SimicsOpenBoardPkg.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
+ gSimicsX58PkgTokenSpaceGuid.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..cb2a60d827
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm
@@ -0,0 +1,281 @@
+;------------------------------------------------------------------------------
+; @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
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
new file mode 100644
index 0000000000..a9673f9c87
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.h
@@ -0,0 +1,218 @@
+/** @file
+ Driver implementing the Tiano Legacy 8259 Protocol
+
+Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _8259_H__
+#define _8259_H__
+
+#include <Protocol/Legacy8259.h>
+#include <Protocol/PciIo.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+// 8259 Hardware definitions
+
+#define LEGACY_MODE_BASE_VECTOR_MASTER 0x08
+#define LEGACY_MODE_BASE_VECTOR_SLAVE 0x70
+
+#define PROTECTED_MODE_BASE_VECTOR_MASTER 0x68
+#define PROTECTED_MODE_BASE_VECTOR_SLAVE 0x70
+
+#define LEGACY_8259_CONTROL_REGISTER_MASTER 0x20
+#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
+#define LEGACY_8259_CONTROL_REGISTER_SLAVE 0xA0
+#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
+
+#define LEGACY_8259_EOI 0x20
+
+// Protocol Function Prototypes
+
+/**
+ Sets the base address for the 8259 master and slave PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
+ @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing to the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetVectorBase (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT8 MasterBase,
+ IN UINT8 SlaveBase
+ );
+
+/**
+ Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ OUT UINT16 *LegacyMask, OPTIONAL
+ OUT UINT16 *LegacyEdgeLevel, OPTIONAL
+ OUT UINT16 *ProtectedMask, OPTIONAL
+ OUT UINT16 *ProtectedEdgeLevel OPTIONAL
+ );
+
+/**
+ Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
+ @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
+ @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
+ @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMask (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN UINT16 *LegacyMask, OPTIONAL
+ IN UINT16 *LegacyEdgeLevel, OPTIONAL
+ IN UINT16 *ProtectedMask, OPTIONAL
+ IN UINT16 *ProtectedEdgeLevel OPTIONAL
+ );
+
+/**
+ Sets the mode of the PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Mode 16-bit real or 32-bit protected mode.
+ @param[in] Mask The value with which to set the interrupt mask.
+ @param[in] EdgeLevel The value with which to set the edge/level mask.
+
+ @retval EFI_SUCCESS The mode was set successfully.
+ @retval EFI_INVALID_PARAMETER The mode was not set.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259SetMode (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_MODE Mode,
+ IN UINT16 *Mask, OPTIONAL
+ IN UINT16 *EdgeLevel OPTIONAL
+ );
+
+/**
+ Translates the IRQ into a vector.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[out] Vector The vector that is assigned to the IRQ.
+
+ @retval EFI_SUCCESS The Vector that matches Irq was returned.
+ @retval EFI_INVALID_PARAMETER Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetVector (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ OUT UINT8 *Vector
+ );
+
+/**
+ Enables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+ @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
+
+ @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EnableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq,
+ IN BOOLEAN LevelTriggered
+ );
+
+/**
+ Disables the specified IRQ.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq IRQ0-IRQ15.
+
+ @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259DisableIrq (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ );
+
+/**
+ Reads the PCI configuration space to get the interrupt number that is assigned to the card.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] PciHandle PCI function for which to return the vector.
+ @param[out] Vector IRQ number that corresponds to the interrupt line.
+
+ @retval EFI_SUCCESS The interrupt line value was read successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259GetInterruptLine (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT UINT8 *Vector
+ );
+
+/**
+ Issues the End of Interrupt (EOI) commands to PICs.
+
+ @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
+ @param[in] Irq The interrupt for which to issue the EOI command.
+
+ @retval EFI_SUCCESS The EOI command was issued.
+ @retval EFI_INVALID_PARAMETER The Irq is not valid.
+
+**/
+EFI_STATUS
+EFIAPI
+Interrupt8259EndOfInterrupt (
+ IN EFI_LEGACY_8259_PROTOCOL *This,
+ IN EFI_8259_IRQ Irq
+ );
+
+#endif
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
new file mode 100644
index 0000000000..e66b21c914
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
@@ -0,0 +1,46 @@
+## @file
+# 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
+#
+# Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Legacy8259
+ MODULE_UNI_FILE = Legacy8259.uni
+ FILE_GUID = 79CA4208-BBA1-4a9a-8456-E1E66A81484E
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = Install8259
+
+[Sources]
+ 8259.c
+ 8259.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ PcAtChipsetPkg/PcAtChipsetPkg.dec
+ SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ DebugLib
+ UefiDriverEntryPoint
+ IoLib
+ PcdLib
+
+[Protocols]
+ gEfiLegacy8259ProtocolGuid ## PRODUCES
+ gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMES
+
+[Pcd]
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask ## CONSUMES
+ gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel ## CONSUMES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ Legacy8259Extra.uni
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
new file mode 100644
index 0000000000..d035292419
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259.uni
@@ -0,0 +1,16 @@
+// /** @file
+// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
+//
+// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
+//
+// Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "8259 Interrupt Controller driver that provides Legacy 8259 protocol"
+
+#string STR_MODULE_DESCRIPTION #language en-US "8259 Interrupt Controller driver that provides Legacy 8259 protocol."
+
diff --git a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
new file mode 100644
index 0000000000..ee43f6923c
--- /dev/null
+++ b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/Legacy8259Extra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Legacy8259 Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Legacy 8259 Interrupt Controller DXE Driver"
+
+
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform
2019-08-09 22:46 ` [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform David Wei
2019-08-15 19:28 ` Nate DeSimone
@ 2019-08-19 23:21 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2 siblings, 0 replies; 37+ messages in thread
From: Nate DeSimone @ 2019-08-19 23:21 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
Hi David,
This patch no longer applies cleanly on the latest edk2-platforms master branch. In addition to addressing the review feedback I previously sent, please rebase your patch.
Thanks,
Nate
-----Original Message-----
From: Wei, David Y
Sent: Friday, August 9, 2019 3:47 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-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform
Add build option in build script for SIMICS QSP Platform
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>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.y.wei@intel.com>
---
Platform/Intel/build.cfg | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg index fc6e4fe824..2ebe09a632 100644
--- a/Platform/Intel/build.cfg
+++ b/Platform/Intel/build.cfg
@@ -54,3 +54,5 @@ NUMBER_OF_PROCESSORS = 0
KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
+WhiskeylakeURvp =
+WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
+BoardX58ICH10 = SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
--
2.16.2.windows.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
2019-08-09 22:46 ` [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
2019-08-15 8:34 ` Nate DeSimone
@ 2019-08-20 1:04 ` Kubacki, Michael A
2019-08-22 22:31 ` David Wei
1 sibling, 1 reply; 37+ messages in thread
From: Kubacki, Michael A @ 2019-08-20 1:04 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Feedback I could not find already noted elsewhere:
1. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c:
There's some style issues throughout the file related to a missing space before opening parenthesis and parameters than span multiple lines.
Some of these are pre-existing in OvmfPkg source. I don't think this is a must have.
2. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 265:
"Confirm if QEMU supports SMRAM." to "Confirm if Simics supports SMRAM."
3. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 275:
"DEBUG((EFI_D_ERROR, "TopOfLowRam =0x%x; TopOfLowRamMb =0x%x \n", TopOfLowRam, TopOfLowRamMb));"
Should be an informational message.
3. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 283:
"DEBUG((EFI_D_ERROR, "MCH_TOLUD =0x%x; \n", PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD))));"
Should be an informational message.
4. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 300 & Line 301 - Should be informational messages as well.
5. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf: Is a dependency on OvmfPkg/OvmfPkg.dec required? This dependency should be avoided.
6. Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore: I don't think this should be an override but should exist in a similar manner
as edk2/OvmfPkg/Sec. The code cannot be upstreamed as-is.
7. /Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c: Some of this messages should probably be verbose not informational.
8. /Silicon/Intel/SimicsX58SktPkg/SktPei.dsc: This file naming convention is unusual. SktPkgPei.dsc is more consistent.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 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-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for
> SimicsX58
>
> 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
> .../Override/UefiCpuPkg/SecCore/SecMain.c | 956
> +++++++++++++++++++++
> .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c | 148 ++++
> .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c | 353 ++++++++
> .../SimicsX58SktPkg/Smm/Access/SmramInternal.c | 199 +++++
> .../Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm | 45 +
> .../Override/UefiCpuPkg/SecCore/SecMain.inf | 71 ++
> .../Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm | 45 +
> Silicon/Intel/SimicsX58SktPkg/SktPei.dsc | 18 +
> .../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf | 9 +
> .../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf | 10 +
> Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf | 17 +
> .../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf | 16 +
> .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf | 52 ++
> .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf | 64 ++
> .../SimicsX58SktPkg/Smm/Access/SmramInternal.h | 81 ++
> 15 files changed, 2084 insertions(+)
> create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.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
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nas
> m
> create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nas
> m
> create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPei.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/Override/UefiCpuPkg/SecCore/SecMain.c
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
> new file mode 100644
> index 0000000000..c52d459ef2
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/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 <IndustryStandard/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_INFO, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32
> (PcdSimicsDxeMemFvBase)));
> + DEBUG ((EFI_D_INFO, "OutputBuffer: 0x%x\n", OutputBuffer));
> + DEBUG ((EFI_D_INFO, "OutputBufferSize: 0x%x\n", OutputBufferSize));
> + DEBUG ((EFI_D_INFO, "ScratchBuffer: 0x%x\n", ScratchBuffer));
> + DEBUG ((EFI_D_INFO, "ScratchBufferSize: 0x%x\n", ScratchBufferSize));
> + DEBUG ((EFI_D_INFO, "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_ERROR, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "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/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..d07d88142a
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> @@ -0,0 +1,353 @@
> +/** @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, 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 <SimicsPlatforms.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 QEMU 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 QEMU.
> + //
> +
> + TopOfLowRam = GetSystemMemorySizeBelow4gb ();
> + ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) == 0);
> + TopOfLowRamMb = TopOfLowRam >> 20;
> + DEBUG((EFI_D_ERROR, "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_ERROR, "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_ERROR, "MCH_TSEGMB =0x%x; \n",
> PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
> + DEBUG((EFI_D_ERROR, "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..898fc25084
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> @@ -0,0 +1,199 @@
> +/** @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 <Guid/AcpiS3Context.h>
> +#include <IndustryStandard/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/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.n
> asm
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.
> nasm
> new file mode 100644
> index 0000000000..19ffb6f86d
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.
> nasm
> @@ -0,0 +1,45 @@
> +; @file
> +; Copyright (c) 2006 - 2013 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/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> new file mode 100644
> index 0000000000..ac993ac1ce
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> @@ -0,0 +1,71 @@
> +## @file
> +# SEC Driver
> +#
> +# Copyright (c) 2008 - 2018 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
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + BaseMemoryLib
> + PeiServicesLib
> + PcdLib
> + UefiCpuLib
> + DebugAgentLib
> + IoLib
> + PeCoffLib
> + PeCoffGetEntryPointLib
> + PeCoffExtraActionLib
> + ExtractGuidedSectionLib
> + LocalApicLib
> + PciCf8Lib
> +
> +[Ppis]
> + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
> +
> +[Pcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> + gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> +
> +[FeaturePcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> diff --git
> a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> asm
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> asm
> new file mode 100644
> index 0000000000..0eb86ec2ca
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> asm
> @@ -0,0 +1,45 @@
> +; @file
> +; Copyright (c) 2006 - 2013 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/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> new file mode 100644
> index 0000000000..0be8be4966
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> @@ -0,0 +1,18 @@
> +## @file
> +# Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> + #
> + # SEC Phase modules
> + #
> + $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf {
> + <LibraryClasses>
> +
> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecom
> pressLib.inf
> + }
> + 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..78eca21a43
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> @@ -0,0 +1,9 @@
> +## @file
> +# Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2017 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..9f037e99d4
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> @@ -0,0 +1,10 @@
> +## @file
> +# Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 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..596d633cd3
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> @@ -0,0 +1,17 @@
> +## @file
> +# Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 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_SECMAIN USE = IA32
> $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf
> +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..9004b9cb83
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> @@ -0,0 +1,16 @@
> +## @file
> +# Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +#INF $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuArchDxe/CpuArchDxe.inf
> +#INF $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuMpDxe/CpuMpDxe.inf
> +!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..2f630b4b95
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> @@ -0,0 +1,52 @@
> +## @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.
> +#
> +# 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
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..1d3b028c85
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> @@ -0,0 +1,64 @@
> +## @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.
> +#
> +# 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
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> + OvmfPkg/OvmfPkg.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 [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10
2019-08-09 22:46 ` [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10 David Wei
2019-08-13 2:01 ` Nate DeSimone
2019-08-15 8:39 ` Nate DeSimone
@ 2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 16:40 ` David Wei
2 siblings, 1 reply; 37+ messages in thread
From: Kubacki, Michael A @ 2019-08-20 1:04 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Feedback I could not find already noted elsewhere:
1. /Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf:
This silicon package should not have a dependency on MinPlatformPkg.dec.
2. /Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf:
This silicon package should not have a dependency on SimicsOpenBoardPkg.dec.
3. Although noted elsewhere: I also prefer Pascal naming as well so SimicsIch10Pkg.
4. /Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.c:
"Reset System Library functions for OVMF" - replace OVMF with Simics ICH10.
5. /Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.inf:
This silicon package INF should not have a dependency on MinPlatformPkg.dec.
6. /Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
This silicon package INF should not have a dependency on MinPlatformPkg.dec.
7. /Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonib/SmmSpiFlashCommonLib:
This silicon package INF should not have a dependency on MinPlatformPkg.dec.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 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-platform patch 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> 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 | 22 +
> .../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 +++++++
> .../IncludePrivate/Library/PchSpiCommonLib.h | 396 +++++++++
> .../Library/ResetSystemLib/ResetSystemLib.inf | 34 +
> .../SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf | 52 ++
> .../BasePchSpiCommonLib/BasePchSpiCommonLib.inf | 33 +
> Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc | 12 +
> .../Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf | 9 +
> .../Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf | 9 +
> .../Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf | 13 +
> .../SmmControl/RuntimeDxe/SmmControl2Dxe.inf | 59 ++
> Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpi.h | 23 +
> Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpiSmm.inf | 44 +
> 25 files changed, 4152 insertions(+)
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.c
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommo
> n.c
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommo
> nSmmLib.c
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCommo
> n.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/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/IncludePrivate/Library/PchSpiCommonLib.h
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.inf
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCo
> mmonLib.inf
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpi
> CommonLib.inf
> create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
> create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
> create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
> create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
> 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..46355e191c
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.c
> @@ -0,0 +1,137 @@
> +/** @file
> + Reset System Library functions for OVMF
> +
> + Copyright (c) 2006 - 2016 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 <IndustryStandard/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/SpiFlashCom
> mon.c
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCom
> mon.c
> new file mode 100644
> index 0000000000..3d4e24eac6
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCom
> mon.c
> @@ -0,0 +1,194 @@
> +/** @file
> + Wrap EFI_SPI_PROTOCOL to provide some library level interfaces
> + for module use.
> +
> + Copyright (c) 2017 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/SpiFlashCom
> monSmmLib.c
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCom
> monSmmLib.c
> new file mode 100644
> index 0000000000..1e5cd0d744
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCom
> monSmmLib.c
> @@ -0,0 +1,54 @@
> +/** @file
> + SMM Library instance of SPI Flash Common Library Class
> +
> + Copyright (c) 2017 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/SpiCom
> mon.c
> b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCom
> mon.c
> new file mode 100644
> index 0000000000..77fb76d7cd
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCom
> mon.c
> @@ -0,0 +1,935 @@
> +/** @file
> + PCH SPI Common Driver implements the SPI Host Controller Compatibility
> Interface.
> +
> + Copyright (c) 2017 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 <IndustryStandard/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..8fb4947b1a
> --- /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 - 2010, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <IndustryStandard/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..19eb469657
> --- /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) 2017 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..f9d340d6df
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/ICH10Pkg.dec
> @@ -0,0 +1,22 @@
> +## @file
> +# Copyright (c) 2014 - 2016 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}}
> diff --git a/Silicon/Intel/SimicsICH10Pkg/Include/Library/SpiFlashCommonLib.h
> b/Silicon/Intel/SimicsICH10Pkg/Include/Library/SpiFlashCommonLib.h
> new file mode 100644
> index 0000000000..c36360bcb0
> --- /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) 2017 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..552ce28d8c
> --- /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) 2017 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..d503d130c8
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/Include/PchLimits.h
> @@ -0,0 +1,94 @@
> +/** @file
> + Build time limits of PCH resources.
> +
> + Copyright (c) 2017 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..00139fc230
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/Include/PchReservedResources.h
> @@ -0,0 +1,60 @@
> +/** @file
> + PCH preserved MMIO resource definitions.
> +
> + Copyright (c) 2017 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..cb5f26c47b
> --- /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) 2017 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..e08721f405
> --- /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) 2017 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..a727aae927
> --- /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) 2017 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/IncludePrivate/Library/PchSpiCommonLib.h
> b/Silicon/Intel/SimicsICH10Pkg/IncludePrivate/Library/PchSpiCommonLib.h
> new file mode 100644
> index 0000000000..5bdec96197
> --- /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) 2017 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..4af462da47
> --- /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 - 2018 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
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> + DebugLib
> + IoLib
> + TimerLib
> diff --git
> a/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlash
> CommonLib.inf
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlash
> CommonLib.inf
> new file mode 100644
> index 0000000000..b5c97f1930
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlash
> CommonLib.inf
> @@ -0,0 +1,52 @@
> +## @file
> +# SMM Library instance of Spi Flash Common Library Class
> +#
> +# Copyright (c) 2017 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
> + MinPlatformPkg/MinPlatformPkg.dec
> +
> +
> +[Pcd]
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
> +
> +[Sources]
> + SpiFlashCommonSmmLib.c
> + SpiFlashCommon.c
> +
> +[Protocols]
> + gEfiSmmSpiProtocolGuid ## CONSUMES
> +
> +[Depex.X64.DXE_SMM_DRIVER]
> + gEfiSmmSpiProtocolGuid
> diff --git
> a/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePch
> SpiCommonLib.inf
> b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePch
> SpiCommonLib.inf
> new file mode 100644
> index 0000000000..11c832e487
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePch
> SpiCommonLib.inf
> @@ -0,0 +1,33 @@
> +## @file
> +# Component description file for the PchSpiCommonLib
> +#
> +# Copyright (c) 2017 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
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> + MinPlatformPkg/MinPlatformPkg.dec
> +
> +[LibraryClasses]
> + IoLib
> + DebugLib
> +
> +[Pcd]
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
> diff --git a/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
> b/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
> new file mode 100644
> index 0000000000..a2d006ee35
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
> @@ -0,0 +1,12 @@
> +## @file
> +# Component description file for the SkyLake SiPkg DXE libraries.
> +#
> +# Copyright (c) 2017 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/BasePc
> hSpiCommonLib.inf
> diff --git a/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
> b/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
> new file mode 100644
> index 0000000000..78eca21a43
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
> @@ -0,0 +1,9 @@
> +## @file
> +# Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> diff --git a/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
> b/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
> new file mode 100644
> index 0000000000..2d3a127c20
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
> @@ -0,0 +1,9 @@
> +## @file
> +# Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> diff --git a/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
> b/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
> new file mode 100644
> index 0000000000..d079c593d9
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
> @@ -0,0 +1,13 @@
> +## @file
> +# Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2017 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/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
> b/Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
> new file mode 100644
> index 0000000000..e23dd9f2fe
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
> @@ -0,0 +1,59 @@
> +## @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.
> +#
> +# 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
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..f7fdd3abbe
> --- /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) 2017 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..265af00ac0
> --- /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) 2017 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 [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
2019-08-09 22:46 ` [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules David Wei
2019-08-15 18:35 ` Nate DeSimone
@ 2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 16:57 ` David Wei
1 sibling, 1 reply; 37+ messages in thread
From: Kubacki, Michael A @ 2019-08-20 1:04 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Feedback I could not find already covered elsewhere:
1. Dsdt.asl: Change "OVMF" in the following line to something else unique to this implementation:
"DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF ", 4) {"
2. BasePchSpiCommonLib.inf: This silicon package should not have a dependency on SimicsOpenBoardPkg.dec.
3. Platform.h: This header guard definition is unusual in style and convention, please correct: "_Platform_h_INCLUDED_"
4. Platform.h: Please update usage of "OVMF" in various signatures throughout the file to something package unique.
5. SimicsX58PlatformConfig.h: Why is this file not in SimicsX58SktPkg?
6. SimicsX58PlatformConfig.h: Change "OVMF" in copyright header to "Simics X58"
7. SimicsPlatforms.h: Change "OVMF" in copyright header to "Simics"
8. SimicsPlatforms.h - Line 16: Follow up on TODO
9. X58Ich10.h: Why is this file in the Simics board package? It should be in the silicon package.
10. LoadLinuxLib.inf: This package should avoid a depdency on OvmfPkg.dec
11. LoadLinuxLib.inf: Library name does not following naming convention. I.e. should be BaseLoadLinuxLib.inf.
12. LoadLinuxLib.inf: This is not truly a BASE library. For example, gBS (boot services) are unavailable in Runtime DXE.
13. Platform.c: Change "OVMF" reference in copyright header.
14. Platform.h: Change "OVMF" reference in copyright header.
15. Cmos.c: It seems CmosAccessLib in BoardModulePkg could be used here to avoid duplication.
16. Fv.c: In MinPlatform, a more intuitive place to manage FVs is in a board-specific instance of PeiReportFvLib
17. General comment: The modules "PlatformPei" and "PlatformDxe" should be avoided in a MinPlatform.
MinPlatformPkg is considered the "platform" and SimicsOpenBoardPkg is considered the "board", therefore this
code should likely be in a board library linked against a PlatformInit module in MinPlatformPkg. Such as BoardInitLib
which is very empty at the moment. At a minimum, if kept as a module for dispatch, the name should not lead to confusion
with platform modules in MinPlatformPkg.
18. PlatformPei.inf: This package should avoid a depdency on OvmfPkg.dec
19. X58SmamSaveStateMap.h: If X58-specific, it should go to SimicsX58SktPkg.
20. SerializeVariablesLib.inf: This package should avoid a depdency on OvmfPkg.dec
21. SimicsOpenBoardPkg.dec: Pcds in the gSimicsX58PkgTokenSpaceGuid token space should be declared in a DEC file
in the SimicsX58SktPkg. SimicsOpenBoardPkg should not be hardcoded to this particular silicon design.
22. SimicsOpenBoardPkg.dec: "X58" should be removed from the copyright header as the DEC is at the package-level
and not the board level.
23. SimicsOpenBoardPkg.dec: The PACKAGE_NAME should not be " SimicsX58Pkg" as the DEC is at package-level and
not Simics board-specific.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 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-platform patch 3/7] SimicsOpenBoardPkg: Add
> SimicsOpenBoardPkg and its modules
>
> Add modules AcpiTables, Include, Library, PlatformDxe, PlatformPei, Policy,
> SmbiosPlatformDxe
> 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
> .../Library/LoadLinuxLib/Linux.c | 662 ++++++++++++++++
> .../Library/LoadLinuxLib/LinuxGdt.c | 175 +++++
> .../Library/NvVarsFileLib/FsAccess.c | 507 ++++++++++++
> .../Library/NvVarsFileLib/NvVarsFileLib.c | 77 ++
> .../SerializeVariablesLib/SerializeVariablesLib.c | 869
> +++++++++++++++++++++
> .../SimicsOpenBoardPkg/PlatformDxe/Platform.c | 865
> ++++++++++++++++++++
> .../PlatformDxe/PlatformConfig.c | 123 +++
> .../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c | 57 ++
> .../PlatformPei/FeatureControl.c | 114 +++
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c | 100 +++
> .../SimicsOpenBoardPkg/PlatformPei/MemDetect.c | 568 ++++++++++++++
> .../SimicsOpenBoardPkg/PlatformPei/Platform.c | 631 +++++++++++++++
> .../SiliconPolicyInitLib/SiliconPolicyInitLib.c | 108 +++
> .../SiliconPolicyUpdateLib.c | 70 ++
> .../SmbiosPlatformDxe/SmbiosPlatformDxe.c | 148 ++++
> .../SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf | 31 +
> .../Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl | 821
> +++++++++++++++++++
> .../Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h | 75 ++
> .../Include/Guid/SimicsX58PlatformConfig.h | 17 +
> .../Include/IndustryStandard/X58Ich10.h | 106 +++
> .../SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h | 298 +++++++
> .../SimicsOpenBoardPkg/Include/Protocol/IsaIo.h | 356 +++++++++
> .../Include/Protocol/Legacy8259.h | 291 +++++++
> .../Include/Register/X58SmramSaveStateMap.h | 178 +++++
> .../SimicsOpenBoardPkg/Include/SimicsPlatforms.h | 54 ++
> .../Library/LoadLinuxLib/Ia32/JumpToKernel.nasm | 41 +
> .../Library/LoadLinuxLib/LoadLinuxLib.h | 52 ++
> .../Library/LoadLinuxLib/LoadLinuxLib.inf | 42 +
> .../Library/LoadLinuxLib/X64/JumpToKernel.nasm | 85 ++
> .../Library/NvVarsFileLib/NvVarsFileLib.h | 55 ++
> .../Library/NvVarsFileLib/NvVarsFileLib.inf | 53 ++
> .../SerializeVariablesLib/SerializeVariablesLib.h | 33 +
> .../SerializeVariablesLib.inf | 36 +
> .../SimicsOpenBoardPkg/PlatformDxe/Platform.h | 37 +
> .../SimicsOpenBoardPkg/PlatformDxe/Platform.inf | 65 ++
> .../SimicsOpenBoardPkg/PlatformDxe/Platform.uni | 31 +
> .../PlatformDxe/PlatformConfig.h | 51 ++
> .../PlatformDxe/PlatformForms.vfr | 67 ++
> .../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h | 50 ++
> .../SimicsOpenBoardPkg/PlatformPei/Platform.h | 93 +++
> .../SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf | 109 +++
> .../SiliconPolicyInitLib/SiliconPolicyInitLib.inf | 38 +
> .../SiliconPolicyUpdateLib.inf | 35 +
> .../SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec | 168 ++++
> .../SmbiosPlatformDxe/SmbiosPlatformDxe.h | 38 +
> .../SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 51 ++
> 46 files changed, 8531 insertions(+)
> 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/SerializeVariablesLib/SerializeVaria
> blesLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconP
> olicyInitLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Silic
> onPolicyUpdateLib.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/SimicsX58PlatformConfig.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap
> .h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> 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/LoadLinuxLib.inf
> 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/SerializeVariablesLib/SerializeVaria
> blesLib.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVaria
> blesLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconP
> olicyInitLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Silic
> onPolicyUpdateLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.i
> nf
>
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> new file mode 100644
> index 0000000000..43a2dee9f6
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> @@ -0,0 +1,662 @@
> +/** @file
> + Copyright (c) 2011 - 2014 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..624fbc37cb
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
> @@ -0,0 +1,175 @@
> +/** @file
> + Initialize GDT for Linux.
> +
> + Copyright (c) 2006 - 2012 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..6ba8784cf3
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
> @@ -0,0 +1,507 @@
> +/** @file
> + File System Access for NvVarsFileLib
> +
> + Copyright (c) 2004 - 2014 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..f60fbc6112
> --- /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) 2009 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/SerializeVariablesLib/SerializeVa
> riablesLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.c
> new file mode 100644
> index 0000000000..c32a978550
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.c
> @@ -0,0 +1,869 @@
> +/** @file
> + Serialize Variables Library implementation
> +
> + Copyright (c) 2004 - 2011 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/PlatformDxe/Platform.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
> new file mode 100644
> index 0000000000..7bede1496d
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
> @@ -0,0 +1,865 @@
> +/** @file
> + This driver effectuates OVMF's 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/SimicsX58PlatformConfig.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 PlatformDxeStrings[];
> +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,
> &gSimicsX58PlatformConfigGuid,
> + 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
> + PlatformDxeStrings, // 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/PlatformDxe/PlatformConfig.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
> new file mode 100644
> index 0000000000..b3b2b34064
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
> @@ -0,0 +1,123 @@
> +/** @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
> +**/
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Guid/SimicsX58PlatformConfig.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, &gSimicsX58PlatformConfigGuid,
> + 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, &gSimicsX58PlatformConfigGuid,
> &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/PlatformPei/Cmos.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
> new file mode 100644
> index 0000000000..fa2c22116c
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
> @@ -0,0 +1,57 @@
> +/** @file
> + PC/AT CMOS access routines
> +
> + Copyright (c) 2006 - 2009 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/PlatformPei/FeatureControl.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
> new file mode 100644
> index 0000000000..692405e417
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/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/PlatformPei/Fv.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
> new file mode 100644
> index 0000000000..818d135c95
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
> @@ -0,0 +1,100 @@
> +/** @file
> + Build FV related hobs for platform.
> +
> + Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PiPei.h"
> +#include "Platform.h"
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>
> +
> +
> +/**
> + 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/PlatformPei/MemDetect.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
> new file mode 100644
> index 0000000000..4c527baef2
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
> @@ -0,0 +1,568 @@
> +/** @file
> + Memory Detection for Virtual Machines.
> +
> + Copyright (c) 2006 - 2016 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/PlatformPei/Platform.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
> new file mode 100644
> index 0000000000..e64bdc7c56
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
> @@ -0,0 +1,631 @@
> +/** @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 ();
> + }
> + PeiFvInitialization ();
> + MemMapInitialization ();
> + }
> +
> + MiscInitialization ();
> + InstallFeatureControlCallback ();
> +
> + return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.c
> new file mode 100644
> index 0000000000..01a9ed40d5
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.c
> @@ -0,0 +1,108 @@
> +/** @file
> + Copyright (c) 2018 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/Sil
> iconPolicyUpdateLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.c
> new file mode 100644
> index 0000000000..6d9da67975
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.c
> @@ -0,0 +1,70 @@
> +/** @file
> + Copyright (c) 2018 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/SmbiosPlatformDxe/SmbiosPlatformDxe
> .c
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .c
> new file mode 100644
> index 0000000000..82a2d60959
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .c
> @@ -0,0 +1,148 @@
> +/** @file
> + This driver installs SMBIOS information for OVMF
> +
> + 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 OVMF
> +
> + @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..839626eb86
> --- /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 - 2018 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..76a8fbc081
> --- /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) 2008 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF ", 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..6395ec11e2
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
> @@ -0,0 +1,75 @@
> +/** @file
> + Platform specific defines for constructing ACPI tables
> +
> + Copyright (c) 2013 - 2008 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _Platform_h_INCLUDED_
> +#define _Platform_h_INCLUDED_
> +
> +#include <PiDxe.h>
> +#include <IndustryStandard/Acpi.h>
> +
> +//
> +// ACPI table information used to initialize tables.
> +//
> +#define EFI_ACPI_OEM_ID 'O','V','M','F',' ',' ' // OEMID 6 bytes long
> +#define EFI_ACPI_OEM_TABLE_ID
> SIGNATURE_64('O','V','M','F','E','D','K','2') // OEM table id 8 bytes long
> +#define EFI_ACPI_OEM_REVISION 0x02000820
> +#define EFI_ACPI_CREATOR_ID SIGNATURE_32('O','V','M','F')
> +#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/SimicsX58PlatformConfig.
> h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.
> h
> new file mode 100644
> index 0000000000..f65f61d74d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.
> h
> @@ -0,0 +1,17 @@
> +/** @file
> + GUID for UEFI variables that are specific to OVMF configuration.
> +
> + Copyright (C) 2014, Red Hat, Inc.
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __SIMICSX58_PLATFORM_CONFIG_H__
> +#define __SIMICSX58_PLATFORM_CONFIG_H__
> +
> +#define SIMICSX58_PLATFORM_CONFIG_GUID \
> +{0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59,
> 0xa5}}
> +
> +extern EFI_GUID gSimicsX58PlatformConfigGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> new file mode 100644
> index 0000000000..36c08176d1
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> @@ -0,0 +1,106 @@
> +/** @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>
> +
> +//
> +// 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/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> new file mode 100644
> index 0000000000..12aeb1227c
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> @@ -0,0 +1,298 @@
> +/** @file
> + EFI ISA ACPI Protocol is used to enumerate and manage all the ISA controllers
> on
> + the platform's ISA Bus.
> +
> +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __ISA_ACPI_H_
> +#define __ISA_ACPI_H_
> +
> +///
> +/// Global ID for the EFI ISA ACPI Protocol.
> +///
> +#define EFI_ISA_ACPI_PROTOCOL_GUID \
> + { \
> + 0x64a892dc, 0x5561, 0x4536, { 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33,
> 0x55 } \
> + }
> +
> +///
> +/// Forward declaration fo the EFI ISA ACPI Protocol
> +///
> +typedef struct _EFI_ISA_ACPI_PROTOCOL EFI_ISA_ACPI_PROTOCOL;
> +
> +///
> +/// ISA ACPI Protocol interrupt resource attributes.
> +///
> +#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_EDGE_SENSITIVE 0x01 ///<
> Edge triggered interrupt on a rising edge.
> +#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_EDGE_SENSITIVE 0x02 ///<
> Edge triggered interrupt on a falling edge.
> +#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_LEVEL_SENSITIVE 0x04 ///<
> Level sensitive interrupt active high.
> +#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_LEVEL_SENSITIVE 0x08 ///<
> Level sensitive interrupt active low.
> +
> +///
> +/// ISA ACPI Protocol DMA resource attributes.
> +///
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_MASK 0x03 ///< Bit mask
> of supported DMA speed attributes.
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_COMPATIBILITY 0x00 ///< ISA
> controller supports compatibility mode DMA transfers.
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_A 0x01 ///< ISA
> controller supports type A DMA transfers.
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_B 0x02 ///< ISA
> controller supports type B DMA transfers.
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_F 0x03 ///< ISA
> controller supports type F DMA transfers.
> +#define EFI_ISA_ACPI_DMA_COUNT_BY_BYTE 0x04 ///< ISA
> controller increments DMA address by bytes (8-bit).
> +#define EFI_ISA_ACPI_DMA_COUNT_BY_WORD 0x08 ///< ISA
> controller increments DMA address by words (16-bit).
> +#define EFI_ISA_ACPI_DMA_BUS_MASTER 0x10 ///< ISA
> controller is a DMA bus master.
> +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT 0x20 ///< ISA
> controller only supports 8-bit DMA transfers.
> +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT_AND_16_BIT 0x40
> ///< ISA controller both 8-bit and 16-bit DMA transfers.
> +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_16_BIT 0x80 ///< ISA
> controller only supports 16-bit DMA transfers.
> +
> +///
> +/// ISA ACPI Protocol MMIO resource attributes
> +///
> +#define EFI_ISA_ACPI_MEMORY_WIDTH_MASK 0x03 ///< Bit mask
> of supported ISA memory width attributes.
> +#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT 0x00 ///< ISA
> MMIO region only supports 8-bit access.
> +#define EFI_ISA_ACPI_MEMORY_WIDTH_16_BIT 0x01 ///< ISA
> MMIO region only supports 16-bit access.
> +#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT_AND_16_BIT 0x02 ///<
> ISA MMIO region supports both 8-bit and 16-bit access.
> +#define EFI_ISA_ACPI_MEMORY_WRITEABLE 0x04 ///< ISA MMIO
> region supports write transactions.
> +#define EFI_ISA_ACPI_MEMORY_CACHEABLE 0x08 ///< ISA MMIO
> region supports being cached.
> +#define EFI_ISA_ACPI_MEMORY_SHADOWABLE 0x10 ///< ISA
> MMIO region may be shadowed.
> +#define EFI_ISA_ACPI_MEMORY_EXPANSION_ROM 0x20 ///< ISA
> MMIO region is an expansion ROM.
> +
> +///
> +/// ISA ACPI Protocol I/O resource attributes
> +///
> +#define EFI_ISA_ACPI_IO_DECODE_10_BITS 0x01 ///< ISA
> controllers uses a 10-bit address decoder for I/O cycles.
> +#define EFI_ISA_ACPI_IO_DECODE_16_BITS 0x02 ///< ISA
> controllers uses a 16-bit address decoder for I/O cycles.
> +
> +///
> +/// EFI ISA ACPI resource type
> +///
> +typedef enum {
> + EfiIsaAcpiResourceEndOfList, ///< Marks the end if a resource list.
> + EfiIsaAcpiResourceIo, ///< ISA I/O port resource range.
> + EfiIsaAcpiResourceMemory, ///< ISA MMIO resource range.
> + EfiIsaAcpiResourceDma, ///< ISA DMA resource.
> + EfiIsaAcpiResourceInterrupt ///< ISA interrupt resource.
> +} EFI_ISA_ACPI_RESOURCE_TYPE;
> +
> +///
> +/// EFI ISA ACPI generic resource structure
> +///
> +typedef struct {
> + EFI_ISA_ACPI_RESOURCE_TYPE Type; ///< The type of resource (I/O,
> MMIO, DMA, Interrupt).
> + UINT32 Attribute; ///< Bit mask of attributes associated with this
> resource. See EFI_ISA_ACPI_xxx macros for valid combinations.
> + UINT32 StartRange; ///< The start of the resource range.
> + UINT32 EndRange; ///< The end of the resource range.
> +} EFI_ISA_ACPI_RESOURCE;
> +
> +///
> +/// EFI ISA ACPI resource device identifier
> +///
> +typedef struct {
> + UINT32 HID; ///< The ACPI Hardware Identifier value associated with an ISA
> controller. Matchs ACPI DSDT contents.
> + UINT32 UID; ///< The ACPI Unique Identifier value associated with an ISA
> controller. Matches ACPI DSDT contents.
> +} EFI_ISA_ACPI_DEVICE_ID;
> +
> +///
> +/// EFI ISA ACPI resource list
> +///
> +typedef struct {
> + EFI_ISA_ACPI_DEVICE_ID Device; ///< The ACPI HID/UID associated with
> an ISA controller.
> + EFI_ISA_ACPI_RESOURCE *ResourceItem; ///< A pointer to the list of
> resources associated with an ISA controller.
> +} EFI_ISA_ACPI_RESOURCE_LIST;
> +
> +/**
> + Enumerates the ISA controllers on an ISA bus.
> +
> + This service allows all the ISA controllers on an ISA bus to be enumerated. If
> + Device is a pointer to a NULL value, then the first ISA controller on the ISA
> + bus is returned in Device and EFI_SUCCESS is returned. If Device is a pointer
> + to a value that was returned on a prior call to DeviceEnumerate(), then the
> next
> + ISA controller on the ISA bus is returned in Device and EFI_SUCCESS is
> returned.
> + If Device is a pointer to the last ISA controller on the ISA bus, then
> + EFI_NOT_FOUND is returned.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[out] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> +
> + @retval EFI_SUCCESS The next ISA controller on the ISA bus was returned.
> + @retval EFI_NOT_FOUND No device found.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_DEVICE_ENUMERATE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + OUT EFI_ISA_ACPI_DEVICE_ID **Device
> + );
> +
> +/**
> + Sets the power state of an ISA controller.
> +
> + This services sets the power state of the ISA controller specified by Device to
> + the power state specified by OnOff. TRUE denotes on, FALSE denotes off.
> + If the power state is sucessfully set on the ISA Controller, then
> + EFI_SUCCESS is returned.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
> + @param[in] OnOff TRUE denotes on, FALSE denotes off.
> +
> + @retval EFI_SUCCESS Successfully set the power state of the ISA controller.
> + @retval Other The ISA controller could not be placed in the requested
> power state.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_SET_DEVICE_POWER)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + IN BOOLEAN OnOff
> + );
> +
> +/**
> + Retrieves the current set of resources associated with an ISA controller.
> +
> + Retrieves the set of I/O, MMIO, DMA, and interrupt resources currently
> + assigned to the ISA controller specified by Device. These resources
> + are returned in ResourceList.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> + @param[out] ResourceList The pointer to the current resource list for Device.
> +
> + @retval EFI_SUCCESS Successfully retrieved the current resource list.
> + @retval EFI_NOT_FOUND The resource list could not be retrieved.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_GET_CUR_RESOURCE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
> + );
> +
> +/**
> + Retrieves the set of possible resources that may be assigned to an ISA
> controller
> + with SetResource().
> +
> + Retrieves the possible sets of I/O, MMIO, DMA, and interrupt resources for
> the
> + ISA controller specified by Device. The sets are returned in ResourceList.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> + @param[out] ResourceList The pointer to the returned list of resource lists.
> +
> + @retval EFI_UNSUPPORTED This service is not supported.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_GET_POS_RESOURCE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
> + );
> +
> +/**
> + Assigns resources to an ISA controller.
> +
> + Assigns the I/O, MMIO, DMA, and interrupt resources specified by
> ResourceList
> + to the ISA controller specified by Device. ResourceList must match a resource
> list returned by GetPosResource() for the same ISA controller.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> + @param[in] ResourceList The pointer to a resources list that must be one of
> the
> + resource lists returned by GetPosResource() for the
> + ISA controller specified by Device.
> +
> + @retval EFI_SUCCESS Successfully set resources on the ISA controller.
> + @retval Other The resources could not be set for the ISA controller.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_SET_RESOURCE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + IN EFI_ISA_ACPI_RESOURCE_LIST *ResourceList
> + );
> +
> +/**
> + Enables or disables an ISA controller.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to the ISA controller to enable/disable.
> + @param[in] Enable TRUE to enable the ISA controller. FALSE to disable the
> + ISA controller.
> +
> + @retval EFI_SUCCESS Successfully enabled/disabled the ISA controller.
> + @retval Other The ISA controller could not be placed in the requested
> state.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_ENABLE_DEVICE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + IN BOOLEAN Enable
> + );
> +
> +/**
> + Initializes an ISA controller, so that it can be used. This service must be called
> + before SetResource(), EnableDevice(), or SetPower() will behave as expected.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
> +
> + @retval EFI_SUCCESS Successfully initialized an ISA controller.
> + @retval Other The ISA controller could not be initialized.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_INIT_DEVICE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device
> + );
> +
> +/**
> + Initializes all the HW states required for the ISA controllers on the ISA bus
> + to be enumerated and managed by the rest of the services in this prorotol.
> + This service must be called before any of the other services in this
> + protocol will function as expected.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> +
> + @retval EFI_SUCCESS Successfully initialized all required hardware states.
> + @retval Other The ISA interface could not be initialized.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_INTERFACE_INIT)(
> + IN EFI_ISA_ACPI_PROTOCOL *This
> + );
> +
> +///
> +/// The EFI_ISA_ACPI_PROTOCOL provides the services to enumerate and
> manage
> +/// ISA controllers on an ISA bus. These services include the ability to initialize,
> +/// enable, disable, and manage the power state of ISA controllers. It also
> +/// includes services to query current resources, query possible resources,
> +/// and assign resources to an ISA controller.
> +///
> +struct _EFI_ISA_ACPI_PROTOCOL {
> + EFI_ISA_ACPI_DEVICE_ENUMERATE DeviceEnumerate;
> + EFI_ISA_ACPI_SET_DEVICE_POWER SetPower;
> + EFI_ISA_ACPI_GET_CUR_RESOURCE GetCurResource;
> + EFI_ISA_ACPI_GET_POS_RESOURCE GetPosResource;
> + EFI_ISA_ACPI_SET_RESOURCE SetResource;
> + EFI_ISA_ACPI_ENABLE_DEVICE EnableDevice;
> + EFI_ISA_ACPI_INIT_DEVICE InitDevice;
> + EFI_ISA_ACPI_INTERFACE_INIT InterfaceInit;
> +};
> +
> +extern EFI_GUID gEfiIsaAcpiProtocolGuid;
> +
> +#endif
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> new file mode 100644
> index 0000000000..30000305fb
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> @@ -0,0 +1,356 @@
> +/** @file
> + ISA I/O Protocol is used by ISA device drivers to perform I/O, MMIO and DMA
> + operations on the ISA controllers they manage.
> +
> +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _EFI_ISA_IO_H_
> +#define _EFI_ISA_IO_H_
> +
> +#include <Protocol/IsaAcpi.h>
> +
> +///
> +/// Global ID for the EFI_ISA_IO_PROTOCOL
> +///
> +#define EFI_ISA_IO_PROTOCOL_GUID \
> + { \
> + 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1,
> 0x4d } \
> + }
> +
> +///
> +/// Forward declaration for the EFI_ISA_IO_PROTOCOL.
> +///
> +typedef struct _EFI_ISA_IO_PROTOCOL EFI_ISA_IO_PROTOCOL;
> +
> +///
> +/// Width of EFI_ISA_IO_PROTOCOL I/O Port and MMIO operations.
> +///
> +typedef enum {
> + EfiIsaIoWidthUint8 = 0, ///< 8-bit operation.
> + EfiIsaIoWidthUint16, ///< 16-bit operation.
> + EfiIsaIoWidthUint32, ///< 32-bit operation
> + EfiIsaIoWidthReserved,
> + EfiIsaIoWidthFifoUint8, ///< 8-bit FIFO operation.
> + EfiIsaIoWidthFifoUint16, ///< 16-bit FIFO operation.
> + EfiIsaIoWidthFifoUint32, ///< 32-bit FIFO operation.
> + EfiIsaIoWidthFifoReserved,
> + EfiIsaIoWidthFillUint8, ///< 8-bit Fill operation.
> + EfiIsaIoWidthFillUint16, ///< 16-bit Fill operation.
> + EfiIsaIoWidthFillUint32, ///< 32-bit Fill operation.
> + EfiIsaIoWidthFillReserved,
> + EfiIsaIoWidthMaximum
> +} EFI_ISA_IO_PROTOCOL_WIDTH;
> +
> +///
> +/// Attributes for the EFI_ISA_IO_PROTOCOL common DMA buffer allocations.
> +///
> +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x080 ///<
> Map a memory range so write are combined.
> +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_CACHED 0x800 ///< Map a
> memory range so all read and write accesses are cached.
> +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000 ///< Disable
> a memory range.
> +
> +///
> +/// Channel attribute for EFI_ISA_IO_PROTOCOL slave DMA requests
> +///
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE 0x001
> ///< Set the speed of the DMA transfer in compatible mode.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_A 0x002 ///< Not
> supported.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_B 0x004 ///< Not
> supported.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_C 0x008 ///< Not
> supported.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8 0x010 ///<
> Request 8-bit DMA transfers. Only available on channels 0..3.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16 0x020 ///<
> Request 16-bit DMA transfers. Only available on channels 4..7.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE 0x040 ///<
> Request a single DMA transfer.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE 0x080
> ///< Request multiple DMA transfers until TC (Terminal Count) or EOP (End of
> Process).
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_AUTO_INITIALIZE 0x100 ///<
> Automatically reload base and count at the end of the DMA transfer.
> +
> +///
> +/// The DMA opreration type for EFI_ISA_IO_PROTOCOL DMA requests.
> +///
> +typedef enum {
> + ///
> + /// A read operation from system memory by a bus master.
> + ///
> + EfiIsaIoOperationBusMasterRead,
> + ///
> + /// A write operation to system memory by a bus master.
> + ///
> + EfiIsaIoOperationBusMasterWrite,
> + ///
> + /// Provides both read and write access to system memory by both the
> processor
> + /// and a bus master. The buffer is coherent from both the processor's and
> the
> + /// bus master's point of view.
> + ///
> + EfiIsaIoOperationBusMasterCommonBuffer,
> + ///
> + /// A read operation from system memory by a slave device.
> + ///
> + EfiIsaIoOperationSlaveRead,
> + ///
> + /// A write operation to system memory by a slave master.
> + ///
> + EfiIsaIoOperationSlaveWrite,
> + EfiIsaIoOperationMaximum
> +} EFI_ISA_IO_PROTOCOL_OPERATION;
> +
> +/**
> + Performs ISA I/O and MMIO Read/Write Cycles
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Width Specifies the width of the I/O or MMIO operation.
> + @param[in] Offset The offset into the ISA I/O or MMIO space to start the
> + operation.
> + @param[in] Count The number of I/O or MMIO operations to perform.
> + @param[in, out] Buffer For read operations, the destination buffer to store
> + the results. For write operations, the source buffer to
> + write data from.
> +
> + @retval EFI_SUCCESS The data was successfully read from or written to
> the device.
> + @retval EFI_UNSUPPORTED The Offset is not valid for this device.
> + @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
> + @retval EFI_OUT_OF_RESOURCES The request could not be completed due
> to a lack of resources.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_IO_MEM)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
> + IN UINT32 Offset,
> + IN UINTN Count,
> + IN OUT VOID *Buffer
> + );
> +
> +///
> +/// Structure of functions for accessing ISA I/O and MMIO space.
> +///
> +typedef struct {
> + ///
> + /// Read from ISA I/O or MMIO space.
> + ///
> + EFI_ISA_IO_PROTOCOL_IO_MEM Read;
> + ///
> + /// Write to ISA I/O or MMIO space.
> + ///
> + EFI_ISA_IO_PROTOCOL_IO_MEM Write;
> +} EFI_ISA_IO_PROTOCOL_ACCESS;
> +
> +/**
> + Copies data from one region of ISA MMIO space to another region of ISA
> + MMIO space.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Width Specifies the width of the MMIO copy operation.
> + @param[in] DestOffset The offset of the destination in ISA MMIO space.
> + @param[in] SrcOffset The offset of the source in ISA MMIO space.
> + @param[in] Count The number tranfers to perform for this copy
> operation.
> +
> + @retval EFI_SUCCESS The data was copied sucessfully.
> + @retval EFI_UNSUPPORTED The DestOffset or SrcOffset is not valid for
> this device.
> + @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
> + @retval EFI_OUT_OF_RESOURCES The request could not be completed due
> to a lack of resources.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_COPY_MEM)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
> + IN UINT32 DestOffset,
> + IN UINT32 SrcOffset,
> + IN UINTN Count
> + );
> +
> +/**
> + Maps a memory region for DMA.
> +
> + This function returns the device-specific addresses required to access system
> memory.
> + This function is used to map system memory for ISA DMA operations. All ISA
> DMA
> + operations must be performed through their mapped addresses, and such
> mappings must
> + be freed with EFI_ISA_IO_PROTOCOL.Unmap() after the DMA operation is
> completed.
> +
> + If the DMA operation is a single read or write data transfer through an ISA bus
> + master, then EfiIsaIoOperationBusMasterRead or
> EfiIsaIoOperationBusMasterWrite
> + is used and the range is unmapped to complete the operation. If the DMA
> operation
> + is a single read or write data transfer through an ISA slave controller, then
> + EfiIsaIoOperationSlaveRead or EfiIsaIoOperationSlaveWrite is used and the
> range
> + is unmapped to complete the operation.
> +
> + If performing a DMA read operation, all the data must be present in system
> memory before the Map() is performed. Similarly,
> + if performing a DMA write operation, the data must not be accessed in system
> + memory until EFI_ISA_IO_PROTOCOL.Unmap() is performed. Bus master
> operations that
> + require both read and write access or require multiple host device
> interactions
> + within the same mapped region must use
> EfiIsaIoOperationBusMasterCommonBuffer.
> + However, only memory allocated via the
> EFI_ISA_IO_PROTOCOL.AllocateBuffer() interface
> + is guaranteed to be able to be mapped for this operation type. In all mapping
> + requests the NumberOfBytes returned may be less than originally requested.
> It is
> + the caller's responsibility to make additional requests to complete the entire
> + transfer.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Operation Indicates the type of DMA (slave or bus
> master),
> + and if the DMA operation is going to read or
> + write to system memory.
> + @param[in] ChannelNumber The slave channel number to use for this
> DMA
> + operation. If Operation and ChannelAttributes
> + shows that this device performs bus mastering
> + DMA, then this field is ignored. The legal
> + range for this field is 0..7.
> + @param[in] ChannelAttributes A bitmask of the attributes used to
> configure
> + the slave DMA channel for this DMA operation.
> + See EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_* for the
> + legal bit combinations.
> + @param[in] HostAddress The system memory address to map to the
> device.
> + @param[in, out] NumberOfBytes On input the number of bytes to map.
> On
> + output the number of bytes that were mapped.
> + @param[out] DeviceAddress The resulting map address for the bus
> master
> + device to use to access the hosts HostAddress.
> + @param[out] Mapping A returned value that must be passed to into
> + EFI_ISA_IO_PROTOCOL.Unmap() to free all the the
> + resources associated with this map request.
> +
> + @retval EFI_SUCCESS The range was mapped for the returned
> NumberOfBytes.
> + @retval EFI_INVALID_PARAMETER The Operation is undefined.
> + @retval EFI_INVALID_PARAMETER The HostAddress is undefined.
> + @retval EFI_UNSUPPORTED The HostAddress can not be mapped as a
> common buffer.
> + @retval EFI_DEVICE_ERROR The system hardware could not map the
> requested address.
> + @retval EFI_OUT_OF_RESOURCES The memory pages could not be
> allocated.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_MAP)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN EFI_ISA_IO_PROTOCOL_OPERATION Operation,
> + IN UINT8 ChannelNumber OPTIONAL,
> + IN UINT32 ChannelAttributes,
> + IN VOID *HostAddress,
> + IN OUT UINTN *NumberOfBytes,
> + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
> + OUT VOID **Mapping
> + );
> +
> +/**
> + Unmaps a memory region that was previously mapped with
> EFI_ISA_IO_PROTOCOL.Map().
> +
> + The EFI_ISA_IO_PROTOCOL.Map() operation is completed and any
> corresponding
> + resources are released. If the operation was EfiIsaIoOperationSlaveWrite
> + or EfiIsaIoOperationBusMasterWrite, the data is committed to system
> memory.
> + Any resources used for the mapping are freed.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Mapping The mapping value returned from
> EFI_ISA_IO_PROTOCOL.Map().
> +
> + @retval EFI_SUCCESS The memory region was unmapped.
> + @retval EFI_DEVICE_ERROR The data was not committed to the target
> system memory.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_UNMAP)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN VOID *Mapping
> + );
> +
> +/**
> + Allocates pages that are suitable for an
> EfiIsaIoOperationBusMasterCommonBuffer
> + mapping.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Type The type allocation to perform.
> + @param[in] MemoryType The type of memory to allocate.
> + @param[in] Pages The number of pages to allocate.
> + @param[out] HostAddress A pointer to store the base address of the
> allocated range.
> + @param[in] Attributes The requested bit mask of attributes for the
> allocated range.
> +
> + @retval EFI_SUCCESS The requested memory pages were allocated.
> + @retval EFI_INVALID_PARAMETER Type is invalid.
> + @retval EFI_INVALID_PARAMETER MemoryType is invalid.
> + @retval EFI_INVALID_PARAMETER HostAddress is NULL.
> + @retval EFI_UNSUPPORTED Attributes is unsupported.
> + @retval EFI_UNSUPPORTED The memory range specified by
> HostAddress, Pages,
> + and Type is not available for common buffer use.
> + @retval EFI_OUT_OF_RESOURCES The memory pages could not be
> allocated.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN EFI_ALLOCATE_TYPE Type,
> + IN EFI_MEMORY_TYPE MemoryType,
> + IN UINTN Pages,
> + OUT VOID **HostAddress,
> + IN UINT64 Attributes
> + );
> +
> +/**
> + Frees a common buffer that was allocated with
> EFI_ISA_IO_PROTOCOL.AllocateBuffer().
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Pages The number of pages to free from the previously
> allocated common buffer.
> + @param[in] HostAddress The base address of the previously allocated
> common buffer.
> +
> +
> + @retval EFI_SUCCESS The requested memory pages were freed.
> + @retval EFI_INVALID_PARAMETER The memory was not allocated with
> EFI_ISA_IO.AllocateBufer().
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_FREE_BUFFER)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN UINTN Pages,
> + IN VOID *HostAddress
> + );
> +
> +/**
> + Flushes a DMA buffer, which forces all DMA posted write transactions to
> complete.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> +
> + @retval EFI_SUCCESS The DMA buffers were flushed.
> + @retval EFI_DEVICE_ERROR The buffers were not flushed due to a
> hardware error.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_FLUSH)(
> + IN EFI_ISA_IO_PROTOCOL *This
> + );
> +
> +///
> +/// The EFI_ISA_IO_PROTOCOL provides the basic Memory, I/O, and DMA
> interfaces
> +/// used to abstract accesses to ISA controllers. There is one
> EFI_ISA_IO_PROTOCOL
> +/// instance for each ISA controller on a ISA bus. A device driver that wishes
> +/// to manage an ISA controller in a system will have to retrieve the
> +/// ISA_PCI_IO_PROTOCOL instance associated with the ISA controller.
> +///
> +struct _EFI_ISA_IO_PROTOCOL {
> + EFI_ISA_IO_PROTOCOL_ACCESS Mem;
> + EFI_ISA_IO_PROTOCOL_ACCESS Io;
> + EFI_ISA_IO_PROTOCOL_COPY_MEM CopyMem;
> + EFI_ISA_IO_PROTOCOL_MAP Map;
> + EFI_ISA_IO_PROTOCOL_UNMAP Unmap;
> + EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer;
> + EFI_ISA_IO_PROTOCOL_FREE_BUFFER FreeBuffer;
> + EFI_ISA_IO_PROTOCOL_FLUSH Flush;
> + ///
> + /// The list of I/O , MMIO, DMA, and Interrupt resources associated with the
> + /// ISA controller abstracted by this instance of the EFI_ISA_IO_PROTOCOL.
> + ///
> + EFI_ISA_ACPI_RESOURCE_LIST *ResourceList;
> + ///
> + /// The size, in bytes, of the ROM image.
> + ///
> + UINT32 RomSize;
> + ///
> + /// A pointer to the in memory copy of the ROM image. The ISA Bus Driver is
> responsible
> + /// for allocating memory for the ROM image, and copying the contents of the
> ROM to memory
> + /// during ISA Bus initialization.
> + ///
> + VOID *RomImage;
> +};
> +
> +extern EFI_GUID gEfiIsaIoProtocolGuid;
> +
> +#endif
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> new file mode 100644
> index 0000000000..c38f2feba7
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> @@ -0,0 +1,291 @@
> +/** @file
> + This protocol abstracts the 8259 interrupt controller. This includes
> + PCI IRQ routing needed to program the PCI Interrupt Line register.
> +
> + Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Revision Reference:
> + This protocol is defined in Framework for EFI Compatibility Support Module
> spec
> + Version 0.97.
> +
> +**/
> +
> +#ifndef _EFI_LEGACY_8259_H_
> +#define _EFI_LEGACY_8259_H_
> +
> +
> +#define EFI_LEGACY_8259_PROTOCOL_GUID \
> + { \
> + 0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed,
> 0xc1 } \
> + }
> +
> +typedef struct _EFI_LEGACY_8259_PROTOCOL
> EFI_LEGACY_8259_PROTOCOL;
> +
> +typedef enum {
> + Efi8259Irq0,
> + Efi8259Irq1,
> + Efi8259Irq2,
> + Efi8259Irq3,
> + Efi8259Irq4,
> + Efi8259Irq5,
> + Efi8259Irq6,
> + Efi8259Irq7,
> + Efi8259Irq8,
> + Efi8259Irq9,
> + Efi8259Irq10,
> + Efi8259Irq11,
> + Efi8259Irq12,
> + Efi8259Irq13,
> + Efi8259Irq14,
> + Efi8259Irq15,
> + Efi8259IrqMax
> +} EFI_8259_IRQ;
> +
> +typedef enum {
> + Efi8259LegacyMode,
> + Efi8259ProtectedMode,
> + Efi8259MaxMode
> +} EFI_8259_MODE;
> +
> +/**
> + Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
> + the legacy mode mask and the protected mode mask. The base address for
> the 8259
> + is different for legacy and protected mode, so two masks are required.
> +
> + @param This The protocol instance pointer.
> + @param MasterBase The base vector for the Master PIC in the 8259
> controller.
> + @param SlaveBase The base vector for the Slave PIC in the 8259
> controller.
> +
> + @retval EFI_SUCCESS The new bases were programmed.
> + @retval EFI_DEVICE_ERROR A device error occured programming the
> vector bases.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_SET_VECTOR_BASE)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT8 MasterBase,
> + IN UINT8 SlaveBase
> + );
> +
> +/**
> + Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
> + the legacy mode mask and the protected mode mask. The base address for
> the 8259
> + is different for legacy and protected mode, so two masks are required.
> +
> + @param This The protocol instance pointer.
> + @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> +
> + @retval EFI_SUCCESS 8259 status returned.
> + @retval EFI_DEVICE_ERROR Error reading 8259.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_GET_MASK)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + OUT UINT16 *LegacyMask, OPTIONAL
> + OUT UINT16 *LegacyEdgeLevel, OPTIONAL
> + OUT UINT16 *ProtectedMask, OPTIONAL
> + OUT UINT16 *ProtectedEdgeLevel OPTIONAL
> + );
> +
> +/**
> + Set the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
> + the legacy mode mask and the protected mode mask. The base address for
> the 8259
> + is different for legacy and protected mode, so two masks are required.
> + Also set the edge/level masks.
> +
> + @param This The protocol instance pointer.
> + @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> +
> + @retval EFI_SUCCESS 8259 status returned.
> + @retval EFI_DEVICE_ERROR Error writing 8259.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_SET_MASK)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT16 *LegacyMask, OPTIONAL
> + IN UINT16 *LegacyEdgeLevel, OPTIONAL
> + IN UINT16 *ProtectedMask, OPTIONAL
> + IN UINT16 *ProtectedEdgeLevel OPTIONAL
> + );
> +
> +/**
> + Set the 8259 mode of operation. The base address for the 8259 is different
> for
> + legacy and protected mode. The legacy mode requires the master 8259 to
> have a
> + master base of 0x08 and the slave base of 0x70. The protected mode base
> locations
> + are not defined. Interrupts must be masked by the caller before this function
> + is called. The interrupt mask from the current mode is saved. The interrupt
> + mask for the new mode is Mask, or if Mask does not exist the previously saved
> + mask is used.
> +
> + @param This The protocol instance pointer.
> + @param Mode The mode of operation. i.e. the real mode or
> protected mode.
> + @param Mask Optional interupt mask for the new mode.
> + @param EdgeLevel Optional trigger mask for the new mode.
> +
> + @retval EFI_SUCCESS 8259 programmed.
> + @retval EFI_DEVICE_ERROR Error writing to 8259.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_SET_MODE)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_MODE Mode,
> + IN UINT16 *Mask, OPTIONAL
> + IN UINT16 *EdgeLevel OPTIONAL
> + );
> +
> +/**
> + Convert from IRQ to processor interrupt vector number.
> +
> + @param This The protocol instance pointer.
> + @param Irq 8259 IRQ0 - IRQ15.
> + @param Vector The processor vector number that matches an Irq.
> +
> + @retval EFI_SUCCESS The Vector matching Irq is returned.
> + @retval EFI_INVALID_PARAMETER The Irq not valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_GET_VECTOR)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + OUT UINT8 *Vector
> + );
> +
> +/**
> + Enable Irq by unmasking interrupt in 8259
> +
> + @param This The protocol instance pointer.
> + @param Irq 8259 IRQ0 - IRQ15.
> + @param LevelTriggered TRUE if level triggered. FALSE if edge triggered.
> +
> + @retval EFI_SUCCESS The Irq was enabled on 8259.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_ENABLE_IRQ)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + IN BOOLEAN LevelTriggered
> + );
> +
> +/**
> + Disable Irq by masking interrupt in 8259
> +
> + @param This The protocol instance pointer.
> + @param Irq 8259 IRQ0 - IRQ15.
> +
> + @retval EFI_SUCCESS The Irq was disabled on 8259.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_DISABLE_IRQ)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + );
> +
> +/**
> + PciHandle represents a PCI config space of a PCI function. Vector
> + represents Interrupt Pin (from PCI config space) and it is the data
> + that is programmed into the Interrupt Line (from the PCI config space)
> + register.
> +
> + @param This The protocol instance pointer.
> + @param PciHandle The PCI function to return the vector for.
> + @param Vector The vector for the function it matches.
> +
> + @retval EFI_SUCCESS A valid Vector was returned.
> + @retval EFI_INVALID_PARAMETER PciHandle not valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_GET_INTERRUPT_LINE)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_HANDLE PciHandle,
> + OUT UINT8 *Vector
> + );
> +
> +/**
> + Send an EOI to 8259
> +
> + @param This The protocol instance pointer.
> + @param Irq 8259 IRQ0 - IRQ15.
> +
> + @retval EFI_SUCCESS EOI was successfully sent to 8259.
> + @retval EFI_INVALID_PARAMETER The Irq isnot valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_END_OF_INTERRUPT)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + );
> +
> +/**
> + @par Protocol Description:
> + Abstracts the 8259 and APIC hardware control between EFI usage and
> + Compatibility16 usage.
> +
> + @param SetVectorBase
> + Sets the vector bases for master and slave PICs.
> +
> + @param GetMask
> + Gets IRQ and edge/level masks for 16-bit real mode and 32-bit protected
> mode.
> +
> + @param SetMask
> + Sets the IRQ and edge\level masks for 16-bit real mode and 32-bit protected
> mode.
> +
> + @param SetMode
> + Sets PIC mode to 16-bit real mode or 32-bit protected mode.
> +
> + @param GetVector
> + Gets the base vector assigned to an IRQ.
> +
> + @param EnableIrq
> + Enables an IRQ.
> +
> + @param DisableIrq
> + Disables an IRQ.
> +
> + @param GetInterruptLine
> + Gets an IRQ that is assigned to a PCI device.
> +
> + @param EndOfInterrupt
> + Issues the end of interrupt command.
> +
> +**/
> +struct _EFI_LEGACY_8259_PROTOCOL {
> + EFI_LEGACY_8259_SET_VECTOR_BASE SetVectorBase;
> + EFI_LEGACY_8259_GET_MASK GetMask;
> + EFI_LEGACY_8259_SET_MASK SetMask;
> + EFI_LEGACY_8259_SET_MODE SetMode;
> + EFI_LEGACY_8259_GET_VECTOR GetVector;
> + EFI_LEGACY_8259_ENABLE_IRQ EnableIrq;
> + EFI_LEGACY_8259_DISABLE_IRQ DisableIrq;
> + EFI_LEGACY_8259_GET_INTERRUPT_LINE GetInterruptLine;
> + EFI_LEGACY_8259_END_OF_INTERRUPT EndOfInterrupt;
> +};
> +
> +extern EFI_GUID gEfiLegacy8259ProtocolGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateM
> ap.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateM
> ap.h
> new file mode 100644
> index 0000000000..640ac4943d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateM
> ap.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/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> new file mode 100644
> index 0000000000..c79111d811
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> @@ -0,0 +1,54 @@
> +/** @file
> + OVMF Platform definitions
> +
> + Copyright (C) 2015, Red Hat, Inc.
> + Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __OVMF_PLATFORMS_H__
> +#define __OVMF_PLATFORMS_H__
> +
> +#include <Library/PciLib.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <IndustryStandard/X58Ich10.h>
> +#include <IndustryStandard/I440FxPiix4.h> // TODO: remove
> +
> +//
> +// 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/LoadLinuxLib/Ia32/JumpToKern
> el.nasm
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKern
> el.nasm
> new file mode 100644
> index 0000000000..3f3cd33c8a
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKern
> el.nasm
> @@ -0,0 +1,41 @@
> +; @file
> +; Copyright (c) 2006 - 2013 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..c4cc4dd8e7
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
> @@ -0,0 +1,52 @@
> +/** @file
> + Boot UEFI Linux.
> +
> + Copyright (c) 2008 - 2013 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/LoadLinuxLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> new file mode 100644
> index 0000000000..89664f4e42
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> @@ -0,0 +1,42 @@
> +## @file
> +#
> +# Copyright (c) 2008 - 2012 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = LoadLinuxLib
> + FILE_GUID = 63CC8497-C9D0-46A8-AC08-49DF92A2FF62
> + MODULE_TYPE = BASE
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = LoadLinuxLib
> +
> +#
> +# 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
> + OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + MemoryAllocationLib
> + BaseMemoryLib
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKerne
> l.nasm
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKerne
> l.nasm
> new file mode 100644
> index 0000000000..79e6b8e7ba
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKerne
> l.nasm
> @@ -0,0 +1,85 @@
> +; @file
> +; Copyright (c) 2006 - 2013 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..92aa038cdd
> --- /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 - 2011 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..e4c3b7ccff
> --- /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 - 2018 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/SerializeVariablesLib/SerializeVa
> riablesLib.h
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.h
> new file mode 100644
> index 0000000000..7e78cd4b21
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.h
> @@ -0,0 +1,33 @@
> +/** @file
> + Serialize Variables Library implementation
> +
> + Copyright (c) 2009 - 2011 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/SerializeVa
> riablesLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.inf
> new file mode 100644
> index 0000000000..25901192b2
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.inf
> @@ -0,0 +1,36 @@
> +## @file
> +# Serialize Variables Library implementation
> +#
> +# This library serializes and deserializes UEFI variables
> +#
> +# Copyright (c) 2006 - 2018 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
> + OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + MemoryAllocationLib
> + UefiBootServicesTableLib
> + UefiRuntimeServicesTableLib
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> new file mode 100644
> index 0000000000..63b5e52575
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> @@ -0,0 +1,37 @@
> +/** @file
> + This driver effectuates OVMF's 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/PlatformDxe/Platform.inf
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
> new file mode 100644
> index 0000000000..804ab59610
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.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 = PlatformDxe
> + 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/SimicsOpenBoardPkg.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
> + gSimicsX58PlatformConfigGuid
> +
> +[Depex]
> + gEfiHiiConfigRoutingProtocolGuid AND
> + gEfiHiiDatabaseProtocolGuid AND
> + gEfiVariableArchProtocolGuid AND
> + gEfiVariableWriteArchProtocolGuid
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
> new file mode 100644
> index 0000000000..6d68cbeb4f
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/PlatformDxe/PlatformConfig.h
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
> new file mode 100644
> index 0000000000..d3f041ddea
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/PlatformDxe/PlatformForms.vfr
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
> new file mode 100644
> index 0000000000..1c02565ebb
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/SimicsX58PlatformConfig.h>
> +#include "Platform.h"
> +
> +formset
> + guid = SIMICSX58_PLATFORM_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 = SIMICSX58_PLATFORM_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/PlatformPei/Cmos.h
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
> new file mode 100644
> index 0000000000..616d2d74cb
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
> @@ -0,0 +1,50 @@
> +/** @file
> + PC/AT CMOS access routines
> +
> + Copyright (c) 2006 - 2009 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/PlatformPei/Platform.h
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
> new file mode 100644
> index 0000000000..5b1a9b5f57
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
> @@ -0,0 +1,93 @@
> +/** @file
> + Platform PEI module include file.
> +
> + Copyright (c) 2006 - 2016 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
> + );
> +
> +EFI_STATUS
> +PeiFvInitialization (
> + 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/PlatformPei/PlatformPei.inf
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
> new file mode 100644
> index 0000000000..eb8048c655
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
> @@ -0,0 +1,109 @@
> +## @file
> +# Platform PEI driver
> +#
> +# This module provides platform specific function to detect boot mode.
> +# Copyright (c) 2006 - 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = PlatformPei
> + 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
> + Fv.c
> + MemDetect.c
> + Platform.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + UefiCpuPkg/UefiCpuPkg.dec
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> + MinPlatformPkg/MinPlatformPkg.dec
> + OvmfPkg/OvmfPkg.dec
> +
> +[Guids]
> + gEfiMemoryTypeInformationGuid
> + gEfiSmmPeiSmramMemoryReserveGuid ## CONSUMES
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + HobLib
> + IoLib
> + PciLib
> + PeiResourcePublicationLib
> + PeiServicesLib
> + PeiServicesTablePointerLib
> + PeimEntryPoint
> + MtrrLib
> + PcdLib
> +
> +[Pcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> + gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> + 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/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.inf
> new file mode 100644
> index 0000000000..b9bcb5d2bd
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.inf
> @@ -0,0 +1,38 @@
> +## @file
> +#
> +# Copyright (c) 2018 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/Sil
> iconPolicyUpdateLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.inf
> new file mode 100644
> index 0000000000..da165ac947
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.inf
> @@ -0,0 +1,35 @@
> +## @file
> +#
> +# Copyright (c) 2018 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/SimicsOpenBoardPkg.dec
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> new file mode 100644
> index 0000000000..17c87aca8c
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> @@ -0,0 +1,168 @@
> +## @file
> +# EFI/Framework Simics X58 platform
> +#
> +# Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + DEC_SPECIFICATION = 0x00010005
> + PACKAGE_NAME = SimicsX58Pkg
> + PACKAGE_GUID = E6A03E0D-5944-4dc6-9292-090D609EDD3A
> + PACKAGE_VERSION = 0.1
> +
> +[Includes]
> + Include
> +
> +[Guids]
> + gSimicsX58PkgTokenSpaceGuid = {0x5b276d20, 0x37d0, 0x4af0, {0x8d,
> 0x04, 0x47, 0x91, 0x2b, 0x7c, 0x1d, 0x44}}
> + gSimicsX58PlatformConfigGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a,
> 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
> +
> +[Protocols]
> + gEfiLegacy8259ProtocolGuid = {0x38321dba, 0x4fe0, 0x4e17, {0x8a,
> 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1}}
> + gEfiIsaAcpiProtocolGuid = {0x64a892dc, 0x5561, 0x4536, {0x92, 0xc7,
> 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55}}
> + gEfiIsaIoProtocolGuid = {0x7ee2bd44, 0x3da0, 0x11d4, {0x9a, 0x38,
> 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
> +
> +[PcdsFixedAtBuild]
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase|0x0|UINT32|0
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize|0x0|UINT32|1
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase|0x0|UINT32|0x15
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize|0x0|UINT32|0x16
> +
> + #TODO: Remove these two when we integrate new PlatformPei
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvBase|0x00800000|UINT32|2
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvSize|0x00500000|UINT32|3
> +
> + ## 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
> +
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase|0x0|UI
> NT32|0x8
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize|0x0|UI
> NT32|0x9
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareFdSize|0x0|UINT32|0xa
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareBlockSize|0|UINT32|0xb
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase|0x0|UI
> NT32|0xc
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase|0x0|UI
> NT32|0xd
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase|0x0
> |UINT32|0xe
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFdBaseAddress|0x0|UINT32|0xf
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase|0x0|UINT32|0x1
> 1
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesSize|0x0|UINT32|0x1
> 2
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|0x0|UINT32|0
> x13
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize|0x0|UINT32|0x
> 14
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase|0x0|UINT32|0x
> 18
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize|0x0|UINT32|0x
> 19
> +
> gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT3
> 2|0x1a
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd|0x0|UINT
> 32|0x1f
> +
> +[PcdsDynamic, PcdsDynamicEx]
> +
> + # TODO: investigate whether next two Pcds are needed
> + gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|0x28
> +
> gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEA
> N|0x10
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0|UINT16|0
> x1b
> +
> + ## The IO port aperture shared by all PCI root bridges.
> + #
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x23
> +
> + ## The 32-bit MMIO aperture shared by all PCI root bridges.
> + #
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT64|0x24
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT64|0x25
> +
> + ## The 64-bit MMIO aperture shared by all PCI root bridges.
> + #
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x26
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x27
> +
> +[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|0x1
> e
> +
> +
> +[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|UIN
> T16|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|0x0
> 0000003
> +
> + ## 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|0x0
> 0000004
> +
> + ## 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|BOOLE
> AN|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|0
> x00000007
> +
> + ## 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|0
> x00000008
> +
> +[PcdsFixedAtBuild, PcdsPatchableInModule]
> + ## FFS filename to find the shell application.
> + # @Prompt FFS Name of Shell Application
> + gSimicsX58PkgTokenSpaceGuid.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 |
> (gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures & 0xF8) == 0
> +
> gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0x0
> 0010040
> \ No newline at end of file
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .h
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .h
> new file mode 100644
> index 0000000000..38a71a3527
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .h
> @@ -0,0 +1,38 @@
> +/** @file
> + This driver installs SMBIOS information for OVMF
> +
> + 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..6adaf0beb7
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .inf
> @@ -0,0 +1,51 @@
> +## @file
> +# This driver installs SMBIOS information for OVMF
> +#
> +# 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/SimicsOpenBoardPkg.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 [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio
2019-08-09 22:46 ` [edk2-platform patch 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio David Wei
2019-08-15 19:01 ` Nate DeSimone
@ 2019-08-20 1:04 ` Kubacki, Michael A
1 sibling, 0 replies; 37+ messages in thread
From: Kubacki, Michael A @ 2019-08-20 1:04 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
My code review comments are already noted elsewhere.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 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-platform patch 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> 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..93e8cefe6c
> --- /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 - 2016 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)SioComponentNameGet
> ControllerName,
> + "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..6fa8c53833
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.c
> @@ -0,0 +1,272 @@
> +/** @file
> + Super I/O specific implementation.
> +
> + Copyright (c) 2010 - 2016 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..0e308a5f18
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.c
> @@ -0,0 +1,600 @@
> +/** @file
> + EFI Driver following Driver Binding Protocol.
> +
> + Copyright (c) 2010 - 2016 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..005d603bdd
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.c
> @@ -0,0 +1,249 @@
> +/** @file
> + Super I/O Interface implementation.
> +
> + Copyright (c) 2010 - 2016 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..36a9069f0f
> --- /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 - 2016 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..a1f558117e
> --- /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 - 2016 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..542b032abb
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/Register.h
> @@ -0,0 +1,15 @@
> +/** @file
> + Super I/O register definitions
> +
> + Copyright (c) 2010 - 2016 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..fea2e9c4c5
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioChip.h
> @@ -0,0 +1,195 @@
> +/** @file
> + Super I/O specific header.
> +
> + Copyright (c) 2010 - 2016 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..7386cb2e19
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioDriver.h
> @@ -0,0 +1,134 @@
> +/** @file
> + Header file for Driver Binding Protocol.
> +
> + Copyright (c) 2010 - 2016 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..6f95090b17
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/LegacySioDxe/SioService.h
> @@ -0,0 +1,143 @@
> +/** @file
> + Super I/O Interface function declarations.
> +
> + Copyright (c) 2010 - 2016 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 [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
2019-08-09 22:46 ` [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform David Wei
2019-08-15 19:38 ` Nate DeSimone
2019-08-15 22:52 ` Nate DeSimone
@ 2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 17:09 ` David Wei
2 siblings, 1 reply; 37+ messages in thread
From: Kubacki, Michael A @ 2019-08-20 1:04 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Agree with Nate's feedback on moving the noted items out of the "Overrides" directory.
Please do submit a patch for style fixes in MinPlatformPkg/Acpi/AcpiTables directly.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 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-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides
> modules for SIMICS QSP Platform
>
> Overrides/MdeModulePkg/Library/PciHostBridgeLib - it is platform related.
> should be Customized
> Overrides/MdeModulePkg/Logo - the Logo image is Customized
> Overrides/MdePkg/Library/BasePciLibCf8 - use the functions specific for SIMICS
>
> 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
> .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++
> .../Library/PlatformBootManagerLib/BdsPlatform.c | 1553
> +++++++++++++++++++
> .../Library/PlatformBootManagerLib/PlatformData.c | 35 +
> .../Overrides/MdeModulePkg/Logo/Logo.c | 154 ++
> .../MdePkg/Library/BasePciLibCf8/PciLib.c | 1221 +++++++++++++++
> .../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 | 417 ++++++
> .../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++
> .../8259InterruptControllerDxe/8259.c | 622 ++++++++
> .../Library/PciHostBridgeLib/PciHostBridge.h | 68 +
> .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 50 +
> .../Library/PlatformBootManagerLib/BdsPlatform.h | 156 ++
> .../PlatformBootManagerLib.inf | 69 +
> .../Overrides/MdeModulePkg/Logo/Logo.bmp | Bin 0 -> 141078 bytes
> .../Overrides/MdeModulePkg/Logo/Logo.idf | 10 +
> .../Overrides/MdeModulePkg/Logo/Logo.inf | 28 +
> .../Overrides/MdeModulePkg/Logo/Logo.uni | 16 +
> .../Overrides/MdeModulePkg/Logo/LogoDxe.inf | 55 +
> .../Overrides/MdeModulePkg/Logo/LogoDxe.uni | 16 +
> .../Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni | 14 +
> .../Overrides/MdeModulePkg/Logo/LogoExtra.uni | 14 +
> .../Library/BasePciLibCf8/DxePciLibX58Ich10.inf | 40 +
> .../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 +
> .../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++
> .../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++
> .../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 73 +
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 281 ++++
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 +
> .../8259InterruptControllerDxe/8259.h | 218 +++
> .../8259InterruptControllerDxe/8259.inf | 46 +
> .../8259InterruptControllerDxe/Legacy8259.uni | 16 +
> .../8259InterruptControllerDxe/Legacy8259Extra.uni | 14 +
> 41 files changed, 11062 insertions(+)
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHos
> tBridgeLib/PciHostBridgeLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/BdsPlatform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/PlatformData.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/
> PciLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/AcpiPlatform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Facs/Facs.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Fadt/Fadt.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Hpet/Hpet.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Wsmt/Wsmt.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Com
> ponentName.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driv
> er.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driv
> erSupportedEfiVersion.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.
> c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initia
> lize.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/8259.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHos
> tBridgeLib/PciHostBridge.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHos
> tBridgeLib/PciHostBridgeLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/BdsPlatform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/PlatformBootManagerLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.bm
> p
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.
> inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.
> uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe
> Extra.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtr
> a.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/
> DxePciLibX58Ich10.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/AcpiPlatform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/AcpiPlatform.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qem
> u.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qem
> uVideoDxe.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.asm
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.sh
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/8259.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/8259.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/Legacy8259.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/Legacy8259Extra.uni
>
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.c
> new file mode 100644
> index 0000000000..2aaa4b3e90
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.c
> @@ -0,0 +1,419 @@
> +/** @file
> + OVMF'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 <IndustryStandard/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/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.c
> new file mode 100644
> index 0000000000..0b66862e46
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.c
> @@ -0,0 +1,1553 @@
> +/** @file
> + Platform BDS customizations.
> +
> + Copyright (c) 2004 - 2018 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
> + //
> + BootLogoEnableLogo();
> +
> + 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/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformData.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformData.c
> new file mode 100644
> index 0000000000..5f1b16dd56
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/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 - 2017 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/Overrides/MdeModulePkg/Logo/Logo.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
> new file mode 100644
> index 0000000000..d4a75ad140
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
> @@ -0,0 +1,154 @@
> +/** @file
> + Logo DXE Driver, install Edkii Platform Logo protocol.
> +
> + Copyright (c) 2016 - 2017 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi.h>
> +#include <Protocol/HiiDatabase.h>
> +#include <Protocol/GraphicsOutput.h>
> +#include <Protocol/HiiImageEx.h>
> +#include <Protocol/PlatformLogo.h>
> +#include <Protocol/HiiPackageList.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +
> +typedef struct {
> + EFI_IMAGE_ID ImageId;
> + EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE Attribute;
> + INTN OffsetX;
> + INTN OffsetY;
> +} LOGO_ENTRY;
> +
> +EFI_HII_IMAGE_EX_PROTOCOL *mHiiImageEx;
> +EFI_HII_HANDLE mHiiHandle;
> +LOGO_ENTRY mLogos[] = {
> + {
> + IMAGE_TOKEN (IMG_LOGO),
> + EdkiiPlatformLogoDisplayAttributeCenter,
> + 0,
> + 0
> + }
> +};
> +
> +/**
> + Load a platform logo image and return its data and attributes.
> +
> + @param This The pointer to this protocol instance.
> + @param Instance The visible image instance is found.
> + @param Image Points to the image.
> + @param Attribute The display attributes of the image returned.
> + @param OffsetX The X offset of the image regarding the Attribute.
> + @param OffsetY The Y offset of the image regarding the Attribute.
> +
> + @retval EFI_SUCCESS The image was fetched successfully.
> + @retval EFI_NOT_FOUND The specified image could not be found.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetImage (
> + IN EDKII_PLATFORM_LOGO_PROTOCOL *This,
> + IN OUT UINT32 *Instance,
> + OUT EFI_IMAGE_INPUT *Image,
> + OUT EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE *Attribute,
> + OUT INTN *OffsetX,
> + OUT INTN *OffsetY
> + )
> +{
> + UINT32 Current;
> + if (Instance == NULL || Image == NULL ||
> + Attribute == NULL || OffsetX == NULL || OffsetY == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Current = *Instance;
> + if (Current >= ARRAY_SIZE (mLogos)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + (*Instance)++;
> + *Attribute = mLogos[Current].Attribute;
> + *OffsetX = mLogos[Current].OffsetX;
> + *OffsetY = mLogos[Current].OffsetY;
> + return mHiiImageEx->GetImageEx (mHiiImageEx, mHiiHandle,
> mLogos[Current].ImageId, Image);
> +}
> +
> +EDKII_PLATFORM_LOGO_PROTOCOL mPlatformLogo = {
> + GetImage
> +};
> +
> +/**
> + Entrypoint of this module.
> +
> + This function is the entrypoint of this module. It installs the Edkii
> + Platform Logo protocol.
> +
> + @param ImageHandle The firmware allocated handle for the EFI image.
> + @param SystemTable A pointer to the EFI System Table.
> +
> + @retval EFI_SUCCESS The entry point is executed successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeLogo (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> + EFI_HII_PACKAGE_LIST_HEADER *PackageList;
> + EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
> + EFI_HANDLE Handle;
> +
> + Status = gBS->LocateProtocol (
> + &gEfiHiiDatabaseProtocolGuid,
> + NULL,
> + (VOID **) &HiiDatabase
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + Status = gBS->LocateProtocol (
> + &gEfiHiiImageExProtocolGuid,
> + NULL,
> + (VOID **) &mHiiImageEx
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + //
> + // Retrieve HII package list from ImageHandle
> + //
> + Status = gBS->OpenProtocol (
> + ImageHandle,
> + &gEfiHiiPackageListProtocolGuid,
> + (VOID **) &PackageList,
> + ImageHandle,
> + NULL,
> + EFI_OPEN_PROTOCOL_GET_PROTOCOL
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "HII Image Package with logo not found in
> PE/COFF resource section\n"));
> + return Status;
> + }
> +
> + //
> + // Publish HII package list to HII Database.
> + //
> + Status = HiiDatabase->NewPackageList (
> + HiiDatabase,
> + PackageList,
> + NULL,
> + &mHiiHandle
> + );
> + if (!EFI_ERROR (Status)) {
> + Handle = NULL;
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &Handle,
> + &gEdkiiPlatformLogoProtocolGuid, &mPlatformLogo,
> + NULL
> + );
> + }
> + return Status;
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/PciLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/PciLib.c
> new file mode 100644
> index 0000000000..7544117a03
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/PciLib.c
> @@ -0,0 +1,1221 @@
> +/** @file
> + PCI Library functions that use
> + (a) I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles, layering
> + on top of one PCI CF8 Library instance; or
> + (b) PCI Library functions that use the 256 MB PCI Express MMIO window to
> + perform PCI Configuration cycles, layering on PCI Express Library.
> +
> + The decision is made in the entry point function, based on the OVMF platform
> + type, and then adhered to during the lifetime of the client module.
> +
> + Copyright (C) 2016, Red Hat, Inc.
> + Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +
> +#include <IndustryStandard/X58Ich10.h>
> +
> +#include <Library/PciLib.h>
> +#include <Library/PciCf8Lib.h>
> +#include <Library/PciExpressLib.h>
> +#include <Library/PcdLib.h>
> +
> +STATIC BOOLEAN mRunningOnIch10;
> +
> +RETURN_STATUS
> +EFIAPI
> +InitializeConfigAccessMethod (
> + VOID
> + )
> +{
> + mRunningOnIch10 = (PcdGet16 (PcdSimicsX58HostBridgePciDevId) ==
> + INTEL_ICH10_DEVICE_ID);
> + return RETURN_SUCCESS;
> +}
> +
> +/**
> + Registers a PCI device so PCI configuration registers may be accessed after
> + SetVirtualAddressMap().
> +
> + Registers the PCI device specified by Address so all the PCI configuration
> registers
> + associated with that PCI device may be accessed after SetVirtualAddressMap()
> is called.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> +
> + @retval RETURN_SUCCESS The PCI device was registered for runtime
> access.
> + @retval RETURN_UNSUPPORTED An attempt was made to call this
> function
> + after ExitBootServices().
> + @retval RETURN_UNSUPPORTED The resources required to access the PCI
> device
> + at runtime could not be mapped.
> + @retval RETURN_OUT_OF_RESOURCES There are not enough resources
> available to
> + complete the registration.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +PciRegisterForRuntimeAccess (
> + IN UINTN Address
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressRegisterForRuntimeAccess (Address) :
> + PciCf8RegisterForRuntimeAccess (Address);
> +}
> +
> +/**
> + Reads an 8-bit PCI configuration register.
> +
> + Reads and returns the 8-bit PCI configuration register specified by Address.
> + This function must guarantee that all PCI read and write operations are
> + serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> +
> + @return The read value from the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciRead8 (
> + IN UINTN Address
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressRead8 (Address) :
> + PciCf8Read8 (Address);
> +}
> +
> +/**
> + Writes an 8-bit PCI configuration register.
> +
> + Writes the 8-bit PCI configuration register specified by Address with the
> + value specified by Value. Value is returned. This function must guarantee
> + that all PCI read and write operations are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param Value The value to write.
> +
> + @return The value written to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciWrite8 (
> + IN UINTN Address,
> + IN UINT8 Value
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressWrite8 (Address, Value) :
> + PciCf8Write8 (Address, Value);
> +}
> +
> +/**
> + Performs a bitwise OR of an 8-bit PCI configuration register with
> + an 8-bit value.
> +
> + Reads the 8-bit PCI configuration register specified by Address, performs a
> + bitwise OR between the read result and the value specified by
> + OrData, and writes the result to the 8-bit PCI configuration register
> + specified by Address. The value written to the PCI configuration register is
> + returned. This function must guarantee that all PCI read and write operations
> + are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param OrData The value to OR with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciOr8 (
> + IN UINTN Address,
> + IN UINT8 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressOr8 (Address, OrData) :
> + PciCf8Or8 (Address, OrData);
> +}
> +
> +/**
> + Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
> + value.
> +
> + Reads the 8-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData, and
> + writes the result to the 8-bit PCI configuration register specified by
> + Address. The value written to the PCI configuration register is returned.
> + This function must guarantee that all PCI read and write operations are
> + serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param AndData The value to AND with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciAnd8 (
> + IN UINTN Address,
> + IN UINT8 AndData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressAnd8 (Address, AndData) :
> + PciCf8And8 (Address, AndData);
> +}
> +
> +/**
> + Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
> + value, followed a bitwise OR with another 8-bit value.
> +
> + Reads the 8-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData,
> + performs a bitwise OR between the result of the AND operation and
> + the value specified by OrData, and writes the result to the 8-bit PCI
> + configuration register specified by Address. The value written to the PCI
> + configuration register is returned. This function must guarantee that all PCI
> + read and write operations are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param AndData The value to AND with the PCI configuration register.
> + @param OrData The value to OR with the result of the AND operation.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciAndThenOr8 (
> + IN UINTN Address,
> + IN UINT8 AndData,
> + IN UINT8 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressAndThenOr8 (Address, AndData, OrData) :
> + PciCf8AndThenOr8 (Address, AndData, OrData);
> +}
> +
> +/**
> + Reads a bit field of a PCI configuration register.
> +
> + Reads the bit field in an 8-bit PCI configuration register. The bit field is
> + specified by the StartBit and the EndBit. The value of the bit field is
> + returned.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If StartBit is greater than 7, then ASSERT().
> + If EndBit is greater than 7, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> +
> + @param Address The PCI configuration register to read.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..7.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..7.
> +
> + @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciBitFieldRead8 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldRead8 (Address, StartBit, EndBit) :
> + PciCf8BitFieldRead8 (Address, StartBit, EndBit);
> +}
> +
> +/**
> + Writes a bit field to a PCI configuration register.
> +
> + Writes Value to the bit field of the PCI configuration register. The bit
> + field is specified by the StartBit and the EndBit. All other bits in the
> + destination PCI configuration register are preserved. The new value of the
> + 8-bit register is returned.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If StartBit is greater than 7, then ASSERT().
> + If EndBit is greater than 7, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If Value is larger than the bitmask value range specified by StartBit and EndBit,
> then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..7.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..7.
> + @param Value The new value of the bit field.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciBitFieldWrite8 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT8 Value
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldWrite8 (Address, StartBit, EndBit, Value) :
> + PciCf8BitFieldWrite8 (Address, StartBit, EndBit, Value);
> +}
> +
> +/**
> + Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
> + writes the result back to the bit field in the 8-bit port.
> +
> + Reads the 8-bit PCI configuration register specified by Address, performs a
> + bitwise OR between the read result and the value specified by
> + OrData, and writes the result to the 8-bit PCI configuration register
> + specified by Address. The value written to the PCI configuration register is
> + returned. This function must guarantee that all PCI read and write operations
> + are serialized. Extra left bits in OrData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If StartBit is greater than 7, then ASSERT().
> + If EndBit is greater than 7, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If OrData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..7.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..7.
> + @param OrData The value to OR with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciBitFieldOr8 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT8 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldOr8 (Address, StartBit, EndBit, OrData) :
> + PciCf8BitFieldOr8 (Address, StartBit, EndBit, OrData);
> +}
> +
> +/**
> + Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
> + AND, and writes the result back to the bit field in the 8-bit register.
> +
> + Reads the 8-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData, and
> + writes the result to the 8-bit PCI configuration register specified by
> + Address. The value written to the PCI configuration register is returned.
> + This function must guarantee that all PCI read and write operations are
> + serialized. Extra left bits in AndData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If StartBit is greater than 7, then ASSERT().
> + If EndBit is greater than 7, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If AndData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..7.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..7.
> + @param AndData The value to AND with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciBitFieldAnd8 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT8 AndData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldAnd8 (Address, StartBit, EndBit, AndData) :
> + PciCf8BitFieldAnd8 (Address, StartBit, EndBit, AndData);
> +}
> +
> +/**
> + Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
> + bitwise OR, and writes the result back to the bit field in the
> + 8-bit port.
> +
> + Reads the 8-bit PCI configuration register specified by Address, performs a
> + bitwise AND followed by a bitwise OR between the read result and
> + the value specified by AndData, and writes the result to the 8-bit PCI
> + configuration register specified by Address. The value written to the PCI
> + configuration register is returned. This function must guarantee that all PCI
> + read and write operations are serialized. Extra left bits in both AndData and
> + OrData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If StartBit is greater than 7, then ASSERT().
> + If EndBit is greater than 7, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If AndData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> + If OrData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..7.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..7.
> + @param AndData The value to AND with the PCI configuration register.
> + @param OrData The value to OR with the result of the AND operation.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciBitFieldAndThenOr8 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT8 AndData,
> + IN UINT8 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData,
> OrData) :
> + PciCf8BitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData);
> +}
> +
> +/**
> + Reads a 16-bit PCI configuration register.
> +
> + Reads and returns the 16-bit PCI configuration register specified by Address.
> + This function must guarantee that all PCI read and write operations are
> + serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> +
> + @return The read value from the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciRead16 (
> + IN UINTN Address
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressRead16 (Address) :
> + PciCf8Read16 (Address);
> +}
> +
> +/**
> + Writes a 16-bit PCI configuration register.
> +
> + Writes the 16-bit PCI configuration register specified by Address with the
> + value specified by Value. Value is returned. This function must guarantee
> + that all PCI read and write operations are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param Value The value to write.
> +
> + @return The value written to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciWrite16 (
> + IN UINTN Address,
> + IN UINT16 Value
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressWrite16 (Address, Value) :
> + PciCf8Write16 (Address, Value);
> +}
> +
> +/**
> + Performs a bitwise OR of a 16-bit PCI configuration register with
> + a 16-bit value.
> +
> + Reads the 16-bit PCI configuration register specified by Address, performs a
> + bitwise OR between the read result and the value specified by
> + OrData, and writes the result to the 16-bit PCI configuration register
> + specified by Address. The value written to the PCI configuration register is
> + returned. This function must guarantee that all PCI read and write operations
> + are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param OrData The value to OR with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciOr16 (
> + IN UINTN Address,
> + IN UINT16 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressOr16 (Address, OrData) :
> + PciCf8Or16 (Address, OrData);
> +}
> +
> +/**
> + Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
> + value.
> +
> + Reads the 16-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData, and
> + writes the result to the 16-bit PCI configuration register specified by
> + Address. The value written to the PCI configuration register is returned.
> + This function must guarantee that all PCI read and write operations are
> + serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param AndData The value to AND with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciAnd16 (
> + IN UINTN Address,
> + IN UINT16 AndData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressAnd16 (Address, AndData) :
> + PciCf8And16 (Address, AndData);
> +}
> +
> +/**
> + Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
> + value, followed a bitwise OR with another 16-bit value.
> +
> + Reads the 16-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData,
> + performs a bitwise OR between the result of the AND operation and
> + the value specified by OrData, and writes the result to the 16-bit PCI
> + configuration register specified by Address. The value written to the PCI
> + configuration register is returned. This function must guarantee that all PCI
> + read and write operations are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param AndData The value to AND with the PCI configuration register.
> + @param OrData The value to OR with the result of the AND operation.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciAndThenOr16 (
> + IN UINTN Address,
> + IN UINT16 AndData,
> + IN UINT16 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressAndThenOr16 (Address, AndData, OrData) :
> + PciCf8AndThenOr16 (Address, AndData, OrData);
> +}
> +
> +/**
> + Reads a bit field of a PCI configuration register.
> +
> + Reads the bit field in a 16-bit PCI configuration register. The bit field is
> + specified by the StartBit and the EndBit. The value of the bit field is
> + returned.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> + If StartBit is greater than 15, then ASSERT().
> + If EndBit is greater than 15, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> +
> + @param Address The PCI configuration register to read.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..15.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..15.
> +
> + @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciBitFieldRead16 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldRead16 (Address, StartBit, EndBit) :
> + PciCf8BitFieldRead16 (Address, StartBit, EndBit);
> +}
> +
> +/**
> + Writes a bit field to a PCI configuration register.
> +
> + Writes Value to the bit field of the PCI configuration register. The bit
> + field is specified by the StartBit and the EndBit. All other bits in the
> + destination PCI configuration register are preserved. The new value of the
> + 16-bit register is returned.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> + If StartBit is greater than 15, then ASSERT().
> + If EndBit is greater than 15, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If Value is larger than the bitmask value range specified by StartBit and EndBit,
> then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..15.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..15.
> + @param Value The new value of the bit field.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciBitFieldWrite16 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT16 Value
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldWrite16 (Address, StartBit, EndBit, Value) :
> + PciCf8BitFieldWrite16 (Address, StartBit, EndBit, Value);
> +}
> +
> +/**
> + Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
> + writes the result back to the bit field in the 16-bit port.
> +
> + Reads the 16-bit PCI configuration register specified by Address, performs a
> + bitwise OR between the read result and the value specified by
> + OrData, and writes the result to the 16-bit PCI configuration register
> + specified by Address. The value written to the PCI configuration register is
> + returned. This function must guarantee that all PCI read and write operations
> + are serialized. Extra left bits in OrData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> + If StartBit is greater than 15, then ASSERT().
> + If EndBit is greater than 15, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If OrData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..15.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..15.
> + @param OrData The value to OR with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciBitFieldOr16 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT16 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldOr16 (Address, StartBit, EndBit, OrData) :
> + PciCf8BitFieldOr16 (Address, StartBit, EndBit, OrData);
> +}
> +
> +/**
> + Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
> + AND, and writes the result back to the bit field in the 16-bit register.
> +
> + Reads the 16-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData, and
> + writes the result to the 16-bit PCI configuration register specified by
> + Address. The value written to the PCI configuration register is returned.
> + This function must guarantee that all PCI read and write operations are
> + serialized. Extra left bits in AndData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> + If StartBit is greater than 15, then ASSERT().
> + If EndBit is greater than 15, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If AndData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..15.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..15.
> + @param AndData The value to AND with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciBitFieldAnd16 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT16 AndData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldAnd16 (Address, StartBit, EndBit, AndData) :
> + PciCf8BitFieldAnd16 (Address, StartBit, EndBit, AndData);
> +}
> +
> +/**
> + Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
> + bitwise OR, and writes the result back to the bit field in the
> + 16-bit port.
> +
> + Reads the 16-bit PCI configuration register specified by Address, performs a
> + bitwise AND followed by a bitwise OR between the read result and
> + the value specified by AndData, and writes the result to the 16-bit PCI
> + configuration register specified by Address. The value written to the PCI
> + configuration register is returned. This function must guarantee that all PCI
> + read and write operations are serialized. Extra left bits in both AndData and
> + OrData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> + If StartBit is greater than 15, then ASSERT().
> + If EndBit is greater than 15, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If AndData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> + If OrData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..15.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..15.
> + @param AndData The value to AND with the PCI configuration register.
> + @param OrData The value to OR with the result of the AND operation.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciBitFieldAndThenOr16 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT16 AndData,
> + IN UINT16 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData,
> OrData) :
> + PciCf8BitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData);
> +}
> +
> +/**
> + Reads a 32-bit PCI configuration register.
> +
> + Reads and returns the 32-bit PCI configuration register specified by Address.
> + This function must guarantee that all PCI read and write operations are
> + serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> +
> + @return The read value from the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciRead32 (
> + IN UINTN Address
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressRead32 (Address) :
> + PciCf8Read32 (Address);
> +}
> +
> +/**
> + Writes a 32-bit PCI configuration register.
> +
> + Writes the 32-bit PCI configuration register specified by Address with the
> + value specified by Value. Value is returned. This function must guarantee
> + that all PCI read and write operations are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param Value The value to write.
> +
> + @return The value written to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciWrite32 (
> + IN UINTN Address,
> + IN UINT32 Value
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressWrite32 (Address, Value) :
> + PciCf8Write32 (Address, Value);
> +}
> +
> +/**
> + Performs a bitwise OR of a 32-bit PCI configuration register with
> + a 32-bit value.
> +
> + Reads the 32-bit PCI configuration register specified by Address, performs a
> + bitwise OR between the read result and the value specified by
> + OrData, and writes the result to the 32-bit PCI configuration register
> + specified by Address. The value written to the PCI configuration register is
> + returned. This function must guarantee that all PCI read and write operations
> + are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param OrData The value to OR with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciOr32 (
> + IN UINTN Address,
> + IN UINT32 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressOr32 (Address, OrData) :
> + PciCf8Or32 (Address, OrData);
> +}
> +
> +/**
> + Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
> + value.
> +
> + Reads the 32-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData, and
> + writes the result to the 32-bit PCI configuration register specified by
> + Address. The value written to the PCI configuration register is returned.
> + This function must guarantee that all PCI read and write operations are
> + serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param AndData The value to AND with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciAnd32 (
> + IN UINTN Address,
> + IN UINT32 AndData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressAnd32 (Address, AndData) :
> + PciCf8And32 (Address, AndData);
> +}
> +
> +/**
> + Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
> + value, followed a bitwise OR with another 32-bit value.
> +
> + Reads the 32-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData,
> + performs a bitwise OR between the result of the AND operation and
> + the value specified by OrData, and writes the result to the 32-bit PCI
> + configuration register specified by Address. The value written to the PCI
> + configuration register is returned. This function must guarantee that all PCI
> + read and write operations are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param AndData The value to AND with the PCI configuration register.
> + @param OrData The value to OR with the result of the AND operation.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciAndThenOr32 (
> + IN UINTN Address,
> + IN UINT32 AndData,
> + IN UINT32 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressAndThenOr32 (Address, AndData, OrData) :
> + PciCf8AndThenOr32 (Address, AndData, OrData);
> +}
> +
> +/**
> + Reads a bit field of a PCI configuration register.
> +
> + Reads the bit field in a 32-bit PCI configuration register. The bit field is
> + specified by the StartBit and the EndBit. The value of the bit field is
> + returned.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> + If StartBit is greater than 31, then ASSERT().
> + If EndBit is greater than 31, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> +
> + @param Address The PCI configuration register to read.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..31.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..31.
> +
> + @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciBitFieldRead32 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldRead32 (Address, StartBit, EndBit) :
> + PciCf8BitFieldRead32 (Address, StartBit, EndBit);
> +}
> +
> +/**
> + Writes a bit field to a PCI configuration register.
> +
> + Writes Value to the bit field of the PCI configuration register. The bit
> + field is specified by the StartBit and the EndBit. All other bits in the
> + destination PCI configuration register are preserved. The new value of the
> + 32-bit register is returned.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> + If StartBit is greater than 31, then ASSERT().
> + If EndBit is greater than 31, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If Value is larger than the bitmask value range specified by StartBit and EndBit,
> then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..31.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..31.
> + @param Value The new value of the bit field.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciBitFieldWrite32 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT32 Value
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldWrite32 (Address, StartBit, EndBit, Value) :
> + PciCf8BitFieldWrite32 (Address, StartBit, EndBit, Value);
> +}
> +
> +/**
> + Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
> + writes the result back to the bit field in the 32-bit port.
> +
> + Reads the 32-bit PCI configuration register specified by Address, performs a
> + bitwise OR between the read result and the value specified by
> + OrData, and writes the result to the 32-bit PCI configuration register
> + specified by Address. The value written to the PCI configuration register is
> + returned. This function must guarantee that all PCI read and write operations
> + are serialized. Extra left bits in OrData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> + If StartBit is greater than 31, then ASSERT().
> + If EndBit is greater than 31, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If OrData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..31.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..31.
> + @param OrData The value to OR with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciBitFieldOr32 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT32 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldOr32 (Address, StartBit, EndBit, OrData) :
> + PciCf8BitFieldOr32 (Address, StartBit, EndBit, OrData);
> +}
> +
> +/**
> + Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
> + AND, and writes the result back to the bit field in the 32-bit register.
> +
> + Reads the 32-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData, and
> + writes the result to the 32-bit PCI configuration register specified by
> + Address. The value written to the PCI configuration register is returned.
> + This function must guarantee that all PCI read and write operations are
> + serialized. Extra left bits in AndData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> + If StartBit is greater than 31, then ASSERT().
> + If EndBit is greater than 31, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If AndData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..31.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..31.
> + @param AndData The value to AND with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciBitFieldAnd32 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT32 AndData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldAnd32 (Address, StartBit, EndBit, AndData) :
> + PciCf8BitFieldAnd32 (Address, StartBit, EndBit, AndData);
> +}
> +
> +/**
> + Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
> + bitwise OR, and writes the result back to the bit field in the
> + 32-bit port.
> +
> + Reads the 32-bit PCI configuration register specified by Address, performs a
> + bitwise AND followed by a bitwise OR between the read result and
> + the value specified by AndData, and writes the result to the 32-bit PCI
> + configuration register specified by Address. The value written to the PCI
> + configuration register is returned. This function must guarantee that all PCI
> + read and write operations are serialized. Extra left bits in both AndData and
> + OrData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> + If StartBit is greater than 31, then ASSERT().
> + If EndBit is greater than 31, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If AndData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> + If OrData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..31.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..31.
> + @param AndData The value to AND with the PCI configuration register.
> + @param OrData The value to OR with the result of the AND operation.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciBitFieldAndThenOr32 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT32 AndData,
> + IN UINT32 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData,
> OrData) :
> + PciCf8BitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData);
> +}
> +
> +/**
> + Reads a range of PCI configuration registers into a caller supplied buffer.
> +
> + Reads the range of PCI configuration registers specified by StartAddress and
> + Size into the buffer specified by Buffer. This function only allows the PCI
> + configuration registers from a single PCI function to be read. Size is
> + returned. When possible 32-bit PCI configuration read cycles are used to read
> + from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
> + and 16-bit PCI configuration read cycles may be used at the beginning and the
> + end of the range.
> +
> + If StartAddress > 0x0FFFFFFF, then ASSERT().
> + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> + If Size > 0 and Buffer is NULL, then ASSERT().
> +
> + @param StartAddress The starting address that encodes the PCI Bus, Device,
> + Function and Register.
> + @param Size The size in bytes of the transfer.
> + @param Buffer The pointer to a buffer receiving the data read.
> +
> + @return Size
> +
> +**/
> +UINTN
> +EFIAPI
> +PciReadBuffer (
> + IN UINTN StartAddress,
> + IN UINTN Size,
> + OUT VOID *Buffer
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressReadBuffer (StartAddress, Size, Buffer) :
> + PciCf8ReadBuffer (StartAddress, Size, Buffer);
> +}
> +
> +/**
> + Copies the data in a caller supplied buffer to a specified range of PCI
> + configuration space.
> +
> + Writes the range of PCI configuration registers specified by StartAddress and
> + Size from the buffer specified by Buffer. This function only allows the PCI
> + configuration registers from a single PCI function to be written. Size is
> + returned. When possible 32-bit PCI configuration write cycles are used to
> + write from StartAdress to StartAddress + Size. Due to alignment restrictions,
> + 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
> + and the end of the range.
> +
> + If StartAddress > 0x0FFFFFFF, then ASSERT().
> + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> + If Size > 0 and Buffer is NULL, then ASSERT().
> +
> + @param StartAddress The starting address that encodes the PCI Bus, Device,
> + Function and Register.
> + @param Size The size in bytes of the transfer.
> + @param Buffer The pointer to a buffer containing the data to write.
> +
> + @return Size written to StartAddress.
> +
> +**/
> +UINTN
> +EFIAPI
> +PciWriteBuffer (
> + IN UINTN StartAddress,
> + IN UINTN Size,
> + IN VOID *Buffer
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressWriteBuffer (StartAddress, Size, Buffer) :
> + PciCf8WriteBuffer (StartAddress, Size, Buffer);
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.c
> new file mode 100644
> index 0000000000..b1d7552792
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.c
> @@ -0,0 +1,1579 @@
> +/** @file
> + ACPI Platform Driver
> +
> + Copyright (c) 2017 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_HEA
> DER *McfgTable;
> +
> EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_AD
> DRESS_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_BA
> SE_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_B
> ASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
> +
> EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVIS
> ION,
> + 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_HEA
> DER) +
> + sizeof
> (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_A
> DDRESS_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_B
> ASE_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/AcpiTa
> bles/Facs/Facs.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Facs/Facs.c
> new file mode 100644
> index 0000000000..a16c13466a
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/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) 2017 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/AcpiTa
> bles/Fadt/Fadt.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Fadt/Fadt.c
> new file mode 100644
> index 0000000000..8aa10a4a5b
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/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) 2017 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/AcpiTa
> bles/Hpet/Hpet.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Hpet/Hpet.c
> new file mode 100644
> index 0000000000..aa386ba149
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/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) 2017 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/AcpiTa
> bles/Wsmt/Wsmt.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Wsmt/Wsmt.c
> new file mode 100644
> index 0000000000..12e2feacb4
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Wsmt/Wsmt.c
> @@ -0,0 +1,46 @@
> +/** @file
> + ACPI WSMT table
> +
> + Copyright (c) 2017 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/Co
> mponentName.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Co
> mponentName.c
> new file mode 100644
> index 0000000000..dd9cc80e42
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Co
> mponentName.c
> @@ -0,0 +1,205 @@
> +/** @file
> + Component name for the QEMU video controller.
> +
> + Copyright (c) 2006 - 2010, 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/Dri
> ver.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> ver.c
> new file mode 100644
> index 0000000000..e49e7a465c
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> ver.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/Dri
> verSupportedEfiVersion.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> verSupportedEfiVersion.c
> new file mode 100644
> index 0000000000..c2d82e7324
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> verSupportedEfiVersion.c
> @@ -0,0 +1,15 @@
> +/** @file
> + Driver supported version protocol for the QEMU video driver.
> +
> + Copyright (c) 2007 - 2010 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/Go
> p.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Go
> p.c
> new file mode 100644
> index 0000000000..19ff5209d2
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Go
> p.c
> @@ -0,0 +1,417 @@
> +/** @file
> + Graphics Output Protocol functions for the QEMU video controller.
> +
> + Copyright (c) 2007 - 2018 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/Ini
> tialize.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Ini
> tialize.c
> new file mode 100644
> index 0000000000..fbf40e9eaf
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Ini
> tialize.c
> @@ -0,0 +1,341 @@
> +/** @file
> + Graphics Output Protocol functions for the QEMU video controller.
> +
> + Copyright (c) 2007 - 2010 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/Vb
> eShim.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.c
> new file mode 100644
> index 0000000000..aa4648f813
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.c
> new file mode 100644
> index 0000000000..b57bacdda4
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.c
> @@ -0,0 +1,622 @@
> +/** @file
> + This contains the installation function for the driver.
> +
> + Copyright (c) 2005 - 2018 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "8259.h"
> +
> +//
> +// Global for the Legacy 8259 Protocol that is produced by this driver
> +//
> +EFI_LEGACY_8259_PROTOCOL mInterrupt8259 = {
> + Interrupt8259SetVectorBase,
> + Interrupt8259GetMask,
> + Interrupt8259SetMask,
> + Interrupt8259SetMode,
> + Interrupt8259GetVector,
> + Interrupt8259EnableIrq,
> + Interrupt8259DisableIrq,
> + Interrupt8259GetInterruptLine,
> + Interrupt8259EndOfInterrupt
> +};
> +
> +//
> +// Global for the handle that the Legacy 8259 Protocol is installed
> +//
> +EFI_HANDLE m8259Handle = NULL;
> +
> +UINT8 mMasterBase = 0xff;
> +UINT8 mSlaveBase = 0xff;
> +EFI_8259_MODE mMode = Efi8259ProtectedMode;
> +UINT16 mProtectedModeMask = 0xffff;
> +UINT16 mLegacyModeMask;
> +UINT16 mProtectedModeEdgeLevel = 0x0000;
> +UINT16 mLegacyModeEdgeLevel;
> +
> +//
> +// Worker Functions
> +//
> +
> +/**
> + Write to mask and edge/level triggered registers of master and slave 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));
> +}
> +
> +/**
> + Read from mask and edge/level triggered registers of master and slave PICs.
> +
> + @param[out] Mask low byte for master PIC mask register,
> + high byte for slave PIC mask register.
> + @param[out] EdgeLevel low byte for master PIC edge/level triggered
> register,
> + high byte for slave PIC edge/level triggered register.
> +
> +**/
> +VOID
> +Interrupt8259ReadMask (
> + OUT UINT16 *Mask,
> + OUT UINT16 *EdgeLevel
> + )
> +{
> + UINT16 MasterValue;
> + UINT16 SlaveValue;
> +
> + if (Mask != NULL) {
> + MasterValue = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
> + SlaveValue = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
> +
> + *Mask = (UINT16) (MasterValue | (SlaveValue << 8));
> + }
> +
> + if (EdgeLevel != NULL) {
> + MasterValue = IoRead8
> (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER);
> + SlaveValue = IoRead8
> (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE);
> +
> + *EdgeLevel = (UINT16) (MasterValue | (SlaveValue << 8));
> + }
> +}
> +
> +//
> +// Legacy 8259 Protocol Interface Functions
> +//
> +
> +/**
> + Sets the base address for the 8259 master and slave PICs.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
> + @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
> +
> + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> + @retval EFI_DEVICE_ERROR There was an error while writing to the 8259
> PIC.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259SetVectorBase (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT8 MasterBase,
> + IN UINT8 SlaveBase
> + )
> +{
> + UINT8 Mask;
> + EFI_TPL OriginalTpl;
> +
> + OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> + //
> + // Set vector base for slave PIC
> + //
> + if (SlaveBase != mSlaveBase) {
> + mSlaveBase = SlaveBase;
> +
> + //
> + // Initialization sequence is needed for setting vector base.
> + //
> +
> + //
> + // Preserve interrtup mask register before initialization sequence
> + // because it will be cleared during initialization
> + //
> + Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
> +
> + //
> + // ICW1: cascade mode, ICW4 write required
> + //
> + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, 0x11);
> +
> + //
> + // ICW2: new vector base (must be multiple of 8)
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, mSlaveBase);
> +
> + //
> + // ICW3: slave indentification code must be 2
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x02);
> +
> + //
> + // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x01);
> +
> + //
> + // Restore interrupt mask register
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, Mask);
> + }
> +
> + //
> + // Set vector base for master PIC
> + //
> + if (MasterBase != mMasterBase) {
> + mMasterBase = MasterBase;
> +
> + //
> + // Initialization sequence is needed for setting vector base.
> + //
> +
> + //
> + // Preserve interrtup mask register before initialization sequence
> + // because it will be cleared during initialization
> + //
> + Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
> +
> + //
> + // ICW1: cascade mode, ICW4 write required
> + //
> + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, 0x11);
> +
> + //
> + // ICW2: new vector base (must be multiple of 8)
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, mMasterBase);
> +
> + //
> + // ICW3: slave PIC is cascaded on IRQ2
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x04);
> +
> + //
> + // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x01);
> +
> + //
> + // Restore interrupt mask register
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, Mask);
> + }
> +
> + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);
> + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER,
> LEGACY_8259_EOI);
> +
> + gBS->RestoreTPL (OriginalTpl);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> + @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
> + @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-
> IRQ15.
> + @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-
> IRQ15.
> + @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-
> IRQ15.
> +
> + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> + @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259GetMask (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + OUT UINT16 *LegacyMask, OPTIONAL
> + OUT UINT16 *LegacyEdgeLevel, OPTIONAL
> + OUT UINT16 *ProtectedMask, OPTIONAL
> + OUT UINT16 *ProtectedEdgeLevel OPTIONAL
> + )
> +{
> + if (LegacyMask != NULL) {
> + *LegacyMask = mLegacyModeMask;
> + }
> +
> + if (LegacyEdgeLevel != NULL) {
> + *LegacyEdgeLevel = mLegacyModeEdgeLevel;
> + }
> +
> + if (ProtectedMask != NULL) {
> + *ProtectedMask = mProtectedModeMask;
> + }
> +
> + if (ProtectedEdgeLevel != NULL) {
> + *ProtectedEdgeLevel = mProtectedModeEdgeLevel;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> + @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
> + @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
> + @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
> + @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-
> IRQ15.
> +
> + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> + @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259SetMask (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT16 *LegacyMask, OPTIONAL
> + IN UINT16 *LegacyEdgeLevel, OPTIONAL
> + IN UINT16 *ProtectedMask, OPTIONAL
> + IN UINT16 *ProtectedEdgeLevel OPTIONAL
> + )
> +{
> + if (LegacyMask != NULL) {
> + mLegacyModeMask = *LegacyMask;
> + }
> +
> + if (LegacyEdgeLevel != NULL) {
> + mLegacyModeEdgeLevel = *LegacyEdgeLevel;
> + }
> +
> + if (ProtectedMask != NULL) {
> + mProtectedModeMask = *ProtectedMask;
> + }
> +
> + if (ProtectedEdgeLevel != NULL) {
> + mProtectedModeEdgeLevel = *ProtectedEdgeLevel;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Sets the mode of the PICs.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Mode 16-bit real or 32-bit protected mode.
> + @param[in] Mask The value with which to set the interrupt mask.
> + @param[in] EdgeLevel The value with which to set the edge/level mask.
> +
> + @retval EFI_SUCCESS The mode was set successfully.
> + @retval EFI_INVALID_PARAMETER The mode was not set.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259SetMode (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_MODE Mode,
> + IN UINT16 *Mask, OPTIONAL
> + IN UINT16 *EdgeLevel OPTIONAL
> + )
> +{
> + if (Mode == mMode) {
> + return EFI_SUCCESS;
> + }
> +
> + if (Mode == Efi8259LegacyMode) {
> + //
> + // In Efi8259ProtectedMode, mask and edge/level trigger registers should
> + // be changed through this protocol, so we can track them in the
> + // corresponding module variables.
> + //
> + Interrupt8259ReadMask (&mProtectedModeMask,
> &mProtectedModeEdgeLevel);
> +
> + if (Mask != NULL) {
> + //
> + // Update the Mask for the new mode
> + //
> + mLegacyModeMask = *Mask;
> + }
> +
> + if (EdgeLevel != NULL) {
> + //
> + // Update the Edge/Level triggered mask for the new mode
> + //
> + mLegacyModeEdgeLevel = *EdgeLevel;
> + }
> +
> + mMode = Mode;
> +
> + //
> + // Write new legacy mode mask/trigger level
> + //
> + Interrupt8259WriteMask (mLegacyModeMask, mLegacyModeEdgeLevel);
> +
> + return EFI_SUCCESS;
> + }
> +
> + if (Mode == Efi8259ProtectedMode) {
> + //
> + // Save the legacy mode mask/trigger level
> + //
> + Interrupt8259ReadMask (&mLegacyModeMask, &mLegacyModeEdgeLevel);
> + //
> + // Always force Timer to be enabled after return from 16-bit code.
> + // This always insures that on next entry, timer is counting.
> + //
> + mLegacyModeMask &= 0xFFFE;
> +
> + if (Mask != NULL) {
> + //
> + // Update the Mask for the new mode
> + //
> + mProtectedModeMask = *Mask;
> + }
> +
> + if (EdgeLevel != NULL) {
> + //
> + // Update the Edge/Level triggered mask for the new mode
> + //
> + mProtectedModeEdgeLevel = *EdgeLevel;
> + }
> +
> + mMode = Mode;
> +
> + //
> + // Write new protected mode mask/trigger level
> + //
> + Interrupt8259WriteMask (mProtectedModeMask,
> mProtectedModeEdgeLevel);
> +
> + return EFI_SUCCESS;
> + }
> +
> + return EFI_INVALID_PARAMETER;
> +}
> +
> +/**
> + Translates the IRQ into a vector.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq IRQ0-IRQ15.
> + @param[out] Vector The vector that is assigned to the IRQ.
> +
> + @retval EFI_SUCCESS The Vector that matches Irq was returned.
> + @retval EFI_INVALID_PARAMETER Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259GetVector (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + OUT UINT8 *Vector
> + )
> +{
> + if ((UINT32)Irq > Efi8259Irq15) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (Irq <= Efi8259Irq7) {
> + *Vector = (UINT8) (mMasterBase + Irq);
> + } else {
> + *Vector = (UINT8) (mSlaveBase + (Irq - Efi8259Irq8));
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Enables the specified IRQ.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq IRQ0-IRQ15.
> + @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
> +
> + @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259EnableIrq (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + IN BOOLEAN LevelTriggered
> + )
> +{
> + if ((UINT32)Irq > Efi8259Irq15) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + mProtectedModeMask = (UINT16) (mProtectedModeMask & ~(1 << Irq));
> + if (LevelTriggered) {
> + mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel | (1 <<
> Irq));
> + } else {
> + mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1
> << Irq));
> + }
> +
> + Interrupt8259WriteMask (mProtectedModeMask,
> mProtectedModeEdgeLevel);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Disables the specified IRQ.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq IRQ0-IRQ15.
> +
> + @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259DisableIrq (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + )
> +{
> + if ((UINT32)Irq > Efi8259Irq15) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + mProtectedModeMask = (UINT16) (mProtectedModeMask | (1 << Irq));
> +
> + mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 <<
> Irq));
> +
> + Interrupt8259WriteMask (mProtectedModeMask,
> mProtectedModeEdgeLevel);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Reads the PCI configuration space to get the interrupt number that is assigned
> to the card.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] PciHandle PCI function for which to return the vector.
> + @param[out] Vector IRQ number that corresponds to the interrupt line.
> +
> + @retval EFI_SUCCESS The interrupt line value was read successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259GetInterruptLine (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_HANDLE PciHandle,
> + OUT UINT8 *Vector
> + )
> +{
> + EFI_PCI_IO_PROTOCOL *PciIo;
> + UINT8 InterruptLine;
> + EFI_STATUS Status;
> +
> + Status = gBS->HandleProtocol (
> + PciHandle,
> + &gEfiPciIoProtocolGuid,
> + (VOID **) &PciIo
> + );
> + if (EFI_ERROR (Status)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + PciIo->Pci.Read (
> + PciIo,
> + EfiPciIoWidthUint8,
> + PCI_INT_LINE_OFFSET,
> + 1,
> + &InterruptLine
> + );
> + //
> + // Interrupt line is same location for standard PCI cards, standard
> + // bridge and CardBus bridge.
> + //
> + *Vector = InterruptLine;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Issues the End of Interrupt (EOI) commands to PICs.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq The interrupt for which to issue the EOI command.
> +
> + @retval EFI_SUCCESS The EOI command was issued.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259EndOfInterrupt (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + )
> +{
> + if ((UINT32)Irq > Efi8259Irq15) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (Irq >= Efi8259Irq8) {
> + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);
> + }
> +
> + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER,
> LEGACY_8259_EOI);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Driver Entry point.
> +
> + @param[in] ImageHandle ImageHandle of the loaded driver.
> + @param[in] SystemTable Pointer to the EFI System Table.
> +
> + @retval EFI_SUCCESS One or more of the drivers returned a success code.
> + @retval !EFI_SUCCESS Error installing Legacy 8259 Protocol.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Install8259 (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> + EFI_8259_IRQ Irq;
> +
> + //
> + // Initialze mask values from PCDs
> + //
> + mLegacyModeMask = PcdGet16 (Pcd8259LegacyModeMask);
> + mLegacyModeEdgeLevel = PcdGet16 (Pcd8259LegacyModeEdgeLevel);
> +
> + //
> + // Clear all pending interrupt
> + //
> + for (Irq = Efi8259Irq0; Irq <= Efi8259Irq15; Irq++) {
> + Interrupt8259EndOfInterrupt (&mInterrupt8259, Irq);
> + }
> +
> + //
> + // Set the 8259 Master base to 0x68 and the 8259 Slave base to 0x70
> + //
> + Status = Interrupt8259SetVectorBase (&mInterrupt8259,
> PROTECTED_MODE_BASE_VECTOR_MASTER,
> PROTECTED_MODE_BASE_VECTOR_SLAVE);
> +
> + //
> + // Set all 8259 interrupts to edge triggered and disabled
> + //
> + Interrupt8259WriteMask (mProtectedModeMask,
> mProtectedModeEdgeLevel);
> +
> + //
> + // Install 8259 Protocol onto a new handle
> + //
> + Status = gBS->InstallProtocolInterface (
> + &m8259Handle,
> + &gEfiLegacy8259ProtocolGuid,
> + EFI_NATIVE_INTERFACE,
> + &mInterrupt8259
> + );
> + return Status;
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridge.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridge.h
> new file mode 100644
> index 0000000000..3bf31067fa
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridge.h
> @@ -0,0 +1,68 @@
> +/** @file
> + Header file of OVMF instance of PciHostBridgeLib.
> +
> + Copyright (c) 2016 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/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.inf
> new file mode 100644
> index 0000000000..8c6de3dca6
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.inf
> @@ -0,0 +1,50 @@
> +## @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/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> + BaseMemoryLib
> + DebugLib
> + DevicePathLib
> + MemoryAllocationLib
> + PciLib
> +
> +[Pcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.h
> new file mode 100644
> index 0000000000..1fb031b752
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.h
> @@ -0,0 +1,156 @@
> +/** @file
> + Platform BDS customizations include file.
> +
> + Copyright (c) 2006 - 2017 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
> + );
> +
> +#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformBootManagerLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformBootManagerLib.inf
> new file mode 100644
> index 0000000000..55da35e87d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformBootManagerLib.inf
> @@ -0,0 +1,69 @@
> +## @file
> +# Platform BDS customizations library.
> +#
> +# Copyright (c) 2007 - 2018 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/SimicsOpenBoardPkg.dec
> + OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + MemoryAllocationLib
> + UefiBootServicesTableLib
> + BaseMemoryLib
> + DebugLib
> + PcdLib
> + UefiBootManagerLib
> + BootLogoLib
> + DevicePathLib
> + PciLib
> + NvVarsFileLib
> + LoadLinuxLib
> + UefiLib
> +
> +[Pcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent
> + gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
> + gSimicsX58PkgTokenSpaceGuid.PcdShellFile
> +
> +[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/Overrides/MdeModulePkg/Logo/Logo.b
> mp
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.b
> mp
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..86d7030833a096f54539
> 3735d931d9f4f2fbf8c0
> 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@*`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+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&BD
> W#
> 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`MbpMs
> Hs!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{s
> 5Us
> 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&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+^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&
> 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}x
> H
> 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@R
> yE}
> 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_XLhaJH
> k9y
> 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#>@h
> Ag0B
> 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+iW
> LO
> 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#;pb9MET
> 3i
> 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^)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*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>_
> pcCU
> zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?cu
> n1%}
> 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~0iLGTxcoR
> PfI4bJ
> 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_^>{+voM4X
> f6<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=&|)SoC
> VC
> 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;op
> qN
> 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?tOz
> z;Fg
> z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSItN
> x
> 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@pcE
> zabu
> 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_v
> 8
> 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;PC7
> PV
> zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^N
> 8-|
> 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>nILXnDZc
> l-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{EARWbyDMH
> hU<^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?NDG
> SQXu
> 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#cQu
> pq
> 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}QPZIah
> 0x
> 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>zMY
> J#!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;1
> y
> 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%ah7VBO
> Y4
> z(Y$TKzJ<J=gNJ^gBA_sfu}}9Z=354HEKK*k*S!&$B(%S5KF_V06KimjU+smdwE?G
> g
> 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~|*N
> yv3
> 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?7t0Oo3
> y|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+0EXJc
> p@|
> 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!Et3gM
> Lk
> TuM~Ktz$*n_Dey{xHWc`O(cS1K
>
> literal 0
> HcmV?d00001
>
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.id
> f
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> df
> new file mode 100644
> index 0000000000..1f79332020
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> df
> @@ -0,0 +1,10 @@
> +// /** @file
> +// Platform Logo image definition file.
> +//
> +// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +#image IMG_LOGO Logo.bmp
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.in
> f
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> nf
> new file mode 100644
> index 0000000000..3380f3c1d5
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> nf
> @@ -0,0 +1,28 @@
> +## @file
> +# The default logo bitmap picture shown on setup screen, which is
> corresponding to gEfiDefaultBmpLogoGuid.
> +#
> +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = Logo
> + MODULE_UNI_FILE = Logo.uni
> + FILE_GUID = 7BB28B99-61BB-11D5-9A5D-0090273FC14D
> + 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 ARM AARCH64
> +#
> +
> +[Binaries]
> + BIN|Logo.bmp|*
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> + LogoExtra.uni
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.u
> ni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.u
> ni
> new file mode 100644
> index 0000000000..9d1bbaffa9
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.u
> ni
> @@ -0,0 +1,16 @@
> +// /** @file
> +// The default logo bitmap picture shown on setup screen, which is
> corresponding to gEfiDefaultBmpLogoGuid.
> +//
> +// This module provides the default logo bitmap picture shown on setup
> screen, which corresponds to gEfiDefaultBmpLogoGuid.
> +//
> +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT #language en-US "Provides the default
> logo bitmap picture shown on setup screen, which corresponds to
> gEfiDefaultBmpLogoGuid"
> +
> +#string STR_MODULE_DESCRIPTION #language en-US "This module
> provides the default logo bitmap picture shown on setup screen, which
> corresponds to gEfiDefaultBmpLogoGuid."
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.inf
> new file mode 100644
> index 0000000000..01102b138f
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.inf
> @@ -0,0 +1,55 @@
> +## @file
> +# The default logo bitmap picture shown on setup screen.
> +#
> +# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = LogoDxe
> + MODULE_UNI_FILE = LogoDxe.uni
> + FILE_GUID = F74D20EE-37E7-48FC-97F7-9B1047749C69
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> +
> + ENTRY_POINT = InitializeLogo
> +#
> +# This flag specifies whether HII resource section is generated into PE image.
> +#
> + UEFI_HII_RESOURCE_SECTION = TRUE
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + Logo.bmp
> + Logo.c
> + Logo.idf
> +
> +[Packages]
> + MdeModulePkg/MdeModulePkg.dec
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + UefiBootServicesTableLib
> + UefiDriverEntryPoint
> + DebugLib
> +
> +[Protocols]
> + gEfiHiiDatabaseProtocolGuid ## CONSUMES
> + gEfiHiiImageExProtocolGuid ## CONSUMES
> + gEfiHiiPackageListProtocolGuid ## PRODUCES CONSUMES
> + gEdkiiPlatformLogoProtocolGuid ## PRODUCES
> +
> +[Depex]
> + gEfiHiiDatabaseProtocolGuid AND
> + gEfiHiiImageExProtocolGuid
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> + LogoDxeExtra.uni
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.uni
> new file mode 100644
> index 0000000000..9635701b60
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.uni
> @@ -0,0 +1,16 @@
> +// /** @file
> +// The default logo bitmap picture shown on setup screen.
> +//
> +// This module provides the default logo bitmap picture shown on setup
> screen, through EDKII Platform Logo protocol.
> +//
> +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT #language en-US "Provides the default
> logo bitmap picture shown on setup screen."
> +
> +#string STR_MODULE_DESCRIPTION #language en-US "This module
> provides the default logo bitmap picture shown on setup screen, through EDKII
> Platform Logo protocol."
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xeExtra.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xeExtra.uni
> new file mode 100644
> index 0000000000..c6ea34b81d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xeExtra.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +// Logo Localized Strings and Content
> +//
> +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +#string STR_PROPERTIES_MODULE_NAME
> +#language en-US
> +"Logo Image File"
> +
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoEx
> tra.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoEx
> tra.uni
> new file mode 100644
> index 0000000000..041179fb75
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoEx
> tra.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +// Logo Localized Strings and Content
> +//
> +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +#string STR_PROPERTIES_MODULE_NAME
> +#language en-US
> +"Logo Image File"
> +
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/DxePciLibX58Ich10.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/DxePciLibX58Ich10.inf
> new file mode 100644
> index 0000000000..e5ca95e20e
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/DxePciLibX58Ich10.inf
> @@ -0,0 +1,40 @@
> +## @file
> +# An instance of the PCI Library that is based on both the PCI CF8 Library and
> +# the PCI Express Library.
> +#
> +# This PciLib instance caches the SimicsX58 platform type (X58-ICH10) in
> +# its entry point function, then delegates function calls to one of the
> +# PciCf8Lib or PciExpressLib "backends" as appropriate.
> +#
> +# Copyright (C) 2016, Red Hat, Inc.
> +# Copyright (c) 2007 - 2014 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = DxePciLibX58Ich10
> + FILE_GUID = FC214B5D-B5B5-4E54-9B28-5E94532E5E2A
> + MODULE_TYPE = BASE
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = PciLib|DXE_DRIVER DXE_RUNTIME_DRIVER
> SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION
> + CONSTRUCTOR = InitializeConfigAccessMethod
> +
> +# VALID_ARCHITECTURES = IA32 X64
> +
> +[Sources]
> + PciLib.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> + PcdLib
> + PciCf8Lib
> + PciExpressLib
> +
> +[Pcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.h
> new file mode 100644
> index 0000000000..2deb2a88eb
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.h
> @@ -0,0 +1,45 @@
> +/** @file
> + This is an implementation of the ACPI platform driver.
> +
> + Copyright (c) 2017 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/AcpiTa
> bles/AcpiPlatform.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.inf
> new file mode 100644
> index 0000000000..b4b52b6622
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.inf
> @@ -0,0 +1,105 @@
> +## @file
> +# Component information file for AcpiPlatform module
> +#
> +# Copyright (c) 2017 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/Qe
> mu.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> mu.h
> new file mode 100644
> index 0000000000..f6ef44a14f
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> mu.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/Qe
> muVideoDxe.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> muVideoDxe.inf
> new file mode 100644
> index 0000000000..8370559016
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> muVideoDxe.inf
> @@ -0,0 +1,73 @@
> +## @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/SimicsOpenBoardPkg.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
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.asm
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.asm
> new file mode 100644
> index 0000000000..cb2a60d827
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.asm
> @@ -0,0 +1,281 @@
> +;------------------------------------------------------------------------------
> +; @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/Vb
> eShim.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.h
> new file mode 100644
> index 0000000000..cc9b6e14cd
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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/Vb
> eShim.sh
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.sh
> new file mode 100644
> index 0000000000..7669f8a219
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.h
> new file mode 100644
> index 0000000000..a9673f9c87
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.h
> @@ -0,0 +1,218 @@
> +/** @file
> + Driver implementing the Tiano Legacy 8259 Protocol
> +
> +Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _8259_H__
> +#define _8259_H__
> +
> +#include <Protocol/Legacy8259.h>
> +#include <Protocol/PciIo.h>
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +
> +#include <IndustryStandard/Pci.h>
> +
> +// 8259 Hardware definitions
> +
> +#define LEGACY_MODE_BASE_VECTOR_MASTER 0x08
> +#define LEGACY_MODE_BASE_VECTOR_SLAVE 0x70
> +
> +#define PROTECTED_MODE_BASE_VECTOR_MASTER 0x68
> +#define PROTECTED_MODE_BASE_VECTOR_SLAVE 0x70
> +
> +#define LEGACY_8259_CONTROL_REGISTER_MASTER 0x20
> +#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
> +#define LEGACY_8259_CONTROL_REGISTER_SLAVE 0xA0
> +#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
> +
> +#define LEGACY_8259_EOI 0x20
> +
> +// Protocol Function Prototypes
> +
> +/**
> + Sets the base address for the 8259 master and slave PICs.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
> + @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
> +
> + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> + @retval EFI_DEVICE_ERROR There was an error while writing to the 8259
> PIC.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259SetVectorBase (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT8 MasterBase,
> + IN UINT8 SlaveBase
> + );
> +
> +/**
> + Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> + @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
> + @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-
> IRQ15.
> + @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-
> IRQ15.
> + @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-
> IRQ15.
> +
> + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> + @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259GetMask (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + OUT UINT16 *LegacyMask, OPTIONAL
> + OUT UINT16 *LegacyEdgeLevel, OPTIONAL
> + OUT UINT16 *ProtectedMask, OPTIONAL
> + OUT UINT16 *ProtectedEdgeLevel OPTIONAL
> + );
> +
> +/**
> + Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> + @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
> + @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
> + @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
> + @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-
> IRQ15.
> +
> + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> + @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259SetMask (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT16 *LegacyMask, OPTIONAL
> + IN UINT16 *LegacyEdgeLevel, OPTIONAL
> + IN UINT16 *ProtectedMask, OPTIONAL
> + IN UINT16 *ProtectedEdgeLevel OPTIONAL
> + );
> +
> +/**
> + Sets the mode of the PICs.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Mode 16-bit real or 32-bit protected mode.
> + @param[in] Mask The value with which to set the interrupt mask.
> + @param[in] EdgeLevel The value with which to set the edge/level mask.
> +
> + @retval EFI_SUCCESS The mode was set successfully.
> + @retval EFI_INVALID_PARAMETER The mode was not set.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259SetMode (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_MODE Mode,
> + IN UINT16 *Mask, OPTIONAL
> + IN UINT16 *EdgeLevel OPTIONAL
> + );
> +
> +/**
> + Translates the IRQ into a vector.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq IRQ0-IRQ15.
> + @param[out] Vector The vector that is assigned to the IRQ.
> +
> + @retval EFI_SUCCESS The Vector that matches Irq was returned.
> + @retval EFI_INVALID_PARAMETER Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259GetVector (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + OUT UINT8 *Vector
> + );
> +
> +/**
> + Enables the specified IRQ.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq IRQ0-IRQ15.
> + @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
> +
> + @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259EnableIrq (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + IN BOOLEAN LevelTriggered
> + );
> +
> +/**
> + Disables the specified IRQ.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq IRQ0-IRQ15.
> +
> + @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259DisableIrq (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + );
> +
> +/**
> + Reads the PCI configuration space to get the interrupt number that is assigned
> to the card.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] PciHandle PCI function for which to return the vector.
> + @param[out] Vector IRQ number that corresponds to the interrupt line.
> +
> + @retval EFI_SUCCESS The interrupt line value was read successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259GetInterruptLine (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_HANDLE PciHandle,
> + OUT UINT8 *Vector
> + );
> +
> +/**
> + Issues the End of Interrupt (EOI) commands to PICs.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq The interrupt for which to issue the EOI command.
> +
> + @retval EFI_SUCCESS The EOI command was issued.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259EndOfInterrupt (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + );
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.inf
> new file mode 100644
> index 0000000000..e66b21c914
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.inf
> @@ -0,0 +1,46 @@
> +## @file
> +# 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
> +#
> +# Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = Legacy8259
> + MODULE_UNI_FILE = Legacy8259.uni
> + FILE_GUID = 79CA4208-BBA1-4a9a-8456-E1E66A81484E
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = Install8259
> +
> +[Sources]
> + 8259.c
> + 8259.h
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + PcAtChipsetPkg/PcAtChipsetPkg.dec
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> + UefiBootServicesTableLib
> + DebugLib
> + UefiDriverEntryPoint
> + IoLib
> + PcdLib
> +
> +[Protocols]
> + gEfiLegacy8259ProtocolGuid ## PRODUCES
> + gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMES
> +
> +[Pcd]
> + gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask ##
> CONSUMES
> + gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel ##
> CONSUMES
> +
> +[Depex]
> + TRUE
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> + Legacy8259Extra.uni
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259.uni
> new file mode 100644
> index 0000000000..d035292419
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259.uni
> @@ -0,0 +1,16 @@
> +// /** @file
> +// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
> +//
> +// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
> +//
> +// Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT #language en-US "8259 Interrupt
> Controller driver that provides Legacy 8259 protocol"
> +
> +#string STR_MODULE_DESCRIPTION #language en-US "8259 Interrupt
> Controller driver that provides Legacy 8259 protocol."
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259Extra.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259Extra.uni
> new file mode 100644
> index 0000000000..ee43f6923c
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259Extra.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +// Legacy8259 Localized Strings and Content
> +//
> +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +#string STR_PROPERTIES_MODULE_NAME
> +#language en-US
> +"Legacy 8259 Interrupt Controller DXE Driver"
> +
> +
> --
> 2.16.2.windows.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 6/7] SimicsOpenBoardPkg: Add board module for QSP Build tip
2019-08-09 22:46 ` [edk2-platform patch 6/7] SimicsOpenBoardPkg: Add board module for QSP Build tip David Wei
@ 2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 17:04 ` David Wei
0 siblings, 1 reply; 37+ messages in thread
From: Kubacki, Michael A @ 2019-08-20 1:04 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Feedback I could not find already noted elsewhere:
1. Remove the batch build files:
- GitEdk2X58ICH10.bat
- bld.bat
- prebuild.bat
The changes must be built with the Python scripts.
2. General comment that applies to multiple files:
Files such as "PlatformPkgBuildOption.dsc" should follow the pre-existing open board package
naming convention. For example, "OpenBoardPkgBuildOption.dsc" in KabylakeOpenBoardPkg.
3. The first commit line should be "SimicsOpenBoardPkg/BoardX58Ich10 to indicate the files relative
to their location in that board directory.
4. Some build option macros in here seem unnecessary. For example, "PURLEY_FLAG". Can you please
check and clean this up?
5. PlatformPkgConfig.dsc: The following PCDs should not always be TRUE as they originate in the
AdvancedFeaturePkg and should only be enabled for an advanced feature boot.
- gAdvancedFeaturePkgTokenSpaceGuid.PcdNetworkEnable
- gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosEnable
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 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-platform patch 6/7] SimicsOpenBoardPkg: 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> 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 +++++
> .../BoardX58ICH10/GitEdk2X58ICH10.bat | 75 +++++
> .../BoardInitLib/PeiBoardInitPostMemLib.inf | 36 +++
> .../Library/BoardInitLib/PeiBoardInitPreMemLib.inf | 38 +++
> .../Library/BoardInitLib/PeiX58ICH10InitLib.h | 16 ++
> .../BoardX58ICH10/PlatformPkgBuildOption.dsc | 89 ++++++
> .../BoardX58ICH10/PlatformPkgConfig.dsc | 56 ++++
> .../BoardX58ICH10/PlatformPkgPcd.dsc | 283 +++++++++++++++++++
> .../BoardX58ICH10/SimicsX58Pkg.fdf.inc | 48 ++++
> .../BoardX58ICH10/SimicsX58PkgIa32X64.dsc | 244 +++++++++++++++++
> .../BoardX58ICH10/SimicsX58PkgIa32X64.fdf | 303
> +++++++++++++++++++++
> .../BoardX58ICH10/VarStore.fdf.inc | 53 ++++
> .../Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat | 139 ++++++++++
> .../BoardX58ICH10/build_config.cfg | 31 +++
> .../SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat | 198
> ++++++++++++++
> 20 files changed, 2000 insertions(+)
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiB
> oardInitPostMemLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiB
> oardInitPreMemLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX
> 58ICH10Detect.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX
> 58ICH10InitPostMemLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX
> 58ICH10InitPreMemLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/DecomprScratchEnd.fdf.i
> nc
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiB
> oardInitPostMemLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiB
> oardInitPreMemLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX
> 58ICH10InitLib.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOption.
> dsc
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58Pkg.fdf.inc
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.ds
> c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.fdf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/VarStore.fdf.inc
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
>
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPostMemLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPostMemLib.c
> new file mode 100644
> index 0000000000..29df3d41ee
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPostMemLib.c
> @@ -0,0 +1,44 @@
> +/** @file
> + Copyright (c) 2018 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/Pe
> iBoardInitPreMemLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPreMemLib.c
> new file mode 100644
> index 0000000000..228fd696df
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPreMemLib.c
> @@ -0,0 +1,110 @@
> +/** @file
> + Copyright (c) 2018 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/Pe
> iX58ICH10Detect.c
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10Detect.c
> new file mode 100644
> index 0000000000..7305ce3181
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10Detect.c
> @@ -0,0 +1,26 @@
> +/** @file
> + Copyright (c) 2018 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/Pe
> iX58ICH10InitPostMemLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitPostMemLib.c
> new file mode 100644
> index 0000000000..002f63a434
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitPostMemLib.c
> @@ -0,0 +1,34 @@
> +/** @file
> + Copyright (c) 2018 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/Pe
> iX58ICH10InitPreMemLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitPreMemLib.c
> new file mode 100644
> index 0000000000..9f0dc91c8a
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitPreMemLib.c
> @@ -0,0 +1,111 @@
> +/** @file
> + Copyright (c) 2018 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 <IndustryStandard/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.fd
> f.inc
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/DecomprScratchEnd.fd
> f.inc
> new file mode 100644
> index 0000000000..394875f205
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/DecomprScratchEnd.fd
> f.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 +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize + 16 +
> gSimicsX58PkgTokenSpaceGuid.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) +
> gSimicsX58PkgTokenSpaceGuid.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 gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd =
> $(DECOMP_SCRATCH_BASE) + $(DECOMP_SCRATCH_SIZE)
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
> new file mode 100644
> index 0000000000..48e9c6b09d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
> @@ -0,0 +1,75 @@
> +@echo off
> +@REM @file
> +@REM Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +@REM
> +@REM SPDX-License-Identifier: BSD-2-Clause-Patent
> +@REM
> +
> +@echo off
> +
> +pushd ..\..\..\..\..\
> +
> +@REM Set WORKSPACE environment.
> +set WORKSPACE=%cd%
> +echo.
> +echo Set WORKSPACE as: %WORKSPACE%
> +echo.
> +
> +@REM Check whether Git has been installed and been added to system path.
> +git --help >nul 2>nul
> +if %ERRORLEVEL% NEQ 0 (
> + echo.
> + echo The 'git' command is not recognized.
> + echo Please make sure that Git is installed and has been added to system path.
> + echo.
> + goto :EOF
> +)
> +
> +@REM Create the Conf directory under WORKSPACE
> +if not exist %WORKSPACE%\Conf (
> + mkdir Conf
> +)
> +
> +@REM Set other environments.
> +@REM Basic Rule:
> +@REM Platform override Silicon override Core
> +@REM Source override Binary
> +
> +set PACKAGES_PATH=%WORKSPACE%\edk2-
> platforms\Platform\Intel;%WORKSPACE%\edk2-
> platforms\Silicon\Intel;%WORKSPACE%\edk2-
> platforms\Drivers;%WORKSPACE%\edk2-non-
> osi\Silicon\Intel;%WORKSPACE%\edk2;%WORKSPACE%
> +
> +set EDK_TOOLS_BIN=%WORKSPACE%\edk2-BaseTools-win32
> +
> +@if not defined PYTHON_HOME (
> + @if exist C:\Python27 (
> + set PYTHON_HOME=C:\Python27
> + )
> +)
> +
> +set EDK_SETUP_OPTION=
> +@rem if python is installed, disable the binary base tools.
> +if defined PYTHON_HOME (
> + set EDK_TOOLS_BIN=
> + set EDK_SETUP_OPTION=Rebuild
> +)
> +pushd %WORKSPACE%\edk2
> +call edksetup.bat %EDK_SETUP_OPTION%
> +popd
> +
> +set openssl_path=%WORKSPACE%
> +
> +popd
> +
> +goto :EOF
> +
> +:Help
> +echo.
> +echo Usage:
> +echo GitEdk2.bat [-w Workspace_Directory] (optional) [-b Branch_Name]
> (optional)
> +echo.
> +echo -w A absolute/relative path to be the workspace.
> +echo Default value is the current directory.
> +echo.
> +echo -b The branch name of the repository. Currently, only master, udk2015,
> +echo trunk (same as master) and bp13 (same as udk2015) are supported.
> +echo Default value is master.
> +echo.
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPostMemLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPostMemLib.inf
> new file mode 100644
> index 0000000000..542b53547f
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPostMemLib.inf
> @@ -0,0 +1,36 @@
> +## @file
> +#
> +# Copyright (c) 2018 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/Pe
> iBoardInitPreMemLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPreMemLib.inf
> new file mode 100644
> index 0000000000..ab1286602b
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPreMemLib.inf
> @@ -0,0 +1,38 @@
> +## @file
> +#
> +# Copyright (c) 2018 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/SimicsOpenBoardPkg.dec
> +
> +[Sources]
> + PeiX58ICH10Detect.c
> + PeiX58ICH10InitPreMemLib.c
> + PeiBoardInitPreMemLib.c
> +
> +[Pcd]
> +
> +[FixedPcd]
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitLib.h
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitLib.h
> new file mode 100644
> index 0000000000..996679e8f5
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitLib.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Copyright (c) 2018 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/PlatformPkgBuildOptio
> n.dsc
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOptio
> n.dsc
> new file mode 100644
> index 0000000000..8bce3c7a4f
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOptio
> n.dsc
> @@ -0,0 +1,89 @@
> +## @file
> +#
> +# Copyright (c) 2018 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 CRB_EDKII_BUILD_OPTIONS = -D CRB_FLAG
> + DEFINE EDKII_CPU_BUILD_OPTIONS = -D PURLEY_FLAG
> + DEFINE TRAD_BUILD_OPTION = -D TRAD_FLAG=1
> + DEFINE SUS_WELL_RESTORE_BUILD_OPTION = -D SUS_WELL_RESTORE=1
> + DEFINE PCH_BUILD_OPTION = -D PCH_SERVER_BIOS_FLAG=1
> + DEFINE SERVER_BUILD_OPTION = -D SERVER_BIOS_FLAG=1
> + DEFINE PCH_PKG_OPTIONS = -D PCH_SPT
> + DEFINE MAX_SOCKET_OPTIONS = -D MAX_SOCKET=2
> +
> + DEFINE EDKII_ALL_PPO_OPTIONS = $(EDKII_CPU_BUILD_OPTIONS)
> + DEFINE PCH_BIOS_BUILD_OPTIONS = $(TRAD_BUILD_OPTION)
> $(ULT_BUILD_OPTION) $(PCH_BUILD_OPTION)
> $(SUS_WELL_RESTORE_BUILD_OPTION) $(SERVER_BUILD_OPTION)
> + DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS =
> $(CRB_EDKII_BUILD_OPTIONS) $(PCH_BIOS_BUILD_OPTIONS)
> $(PCH_PKG_OPTIONS) $(EDKII_ALL_PPO_OPTIONS)
> $(SPARING_SCRATCHPAD_OPTION) $(TRACE_HUB_DEBUG_BUILD_OPTIONS)
> $(TRACE_HUB_INIT_BUILD_OPTIONS) $(MAX_SOCKET_OPTIONS) -D
> EFI_PCI_IOV_SUPPORT -D WHEA_SUPPORT -D SKX_HOST -D CLX_HOST
> +
> +!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/PlatformPkgConfig.dsc
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
> new file mode 100644
> index 0000000000..f0ab846290
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
> @@ -0,0 +1,56 @@
> +## @file
> +#
> +# Copyright (c) 2018 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/PlatformPkgPcd.dsc
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
> new file mode 100644
> index 0000000000..dc70adee34
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
> @@ -0,0 +1,283 @@
> +## @file
> +#
> +# Copyright (c) 2018 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.PcdResetOnMemoryTypeInformationChan
> ge|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|0x17000
> 00
> +
> + 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|0x200910
> 13
> +
> + ## 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.PcdResetOnMemoryTypeInformationChan
> ge|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
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress|0xFFE00000
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize|0x00200000
> +
> +[PcdsDynamicExDefault.common.DEFAULT]
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|30000
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress|0
> +
> +[PcdsDynamicExHii.common.DEFAULT]
> +
> gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobal
> VariableGuid|0x0|50 # Variable: L"Timeout"
> +
> gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSuppo
> rt"|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|0x204657303
> 0363253
> +
> +[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|0x800
> 0
> + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xc000
> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0xc000
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x200
> 0
> +
> 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
> +
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase|0x0
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize|0x0
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base|0x0
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size|0x0
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base|0x0
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size|0x800000000
> +
> +
> gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0StringBiosVersion|"Ve
> r.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/SimicsX58Pkg.fdf.inc
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58Pkg.fdf.inc
> new file mode 100644
> index 0000000000..f42e8b0e0e
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58Pkg.fdf.inc
> @@ -0,0 +1,48 @@
> +## @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 gSimicsX58PkgTokenSpaceGuid.PcdSimicsFdBaseAddress =
> $(FW_BASE_ADDRESS)
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareFdSize = $(FW_SIZE)
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareBlockSize =
> $(BLOCK_SIZE)
> +
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase =
> $(FW_BASE_ADDRESS)
> +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize =
> 0xE000
> +
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase =
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase +
> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize =
> $(BLOCK_SIZE)
> +
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase
> = gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize
> +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize =
> $(BLOCK_SIZE)
> +
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase =
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase +
> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize =
> 0x10000
> +
> +DEFINE MEMFD_BASE_ADDRESS = 0x800000
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.
> dsc
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.
> dsc
> new file mode 100644
> index 0000000000..66ac16a940
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.
> dsc
> @@ -0,0 +1,244 @@
> +## @file
> +#
> +# Copyright (c) 2018 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)/SimicsX58PkgIa32X64.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)/PlatformPkgConfig.dsc
> + !include MinPlatformPkg/Include/Dsc/CoreCommonLib.dsc
> + !include $(PCH_PKG)/PchCommonLib.dsc
> +
> +[LibraryClasses]
> +
> ReportFvLib|MinPlatformPkg/PlatformInit/Library/PeiReportFvLib/PeiReportFv
> Lib.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/SerializeVari
> ablesLib.inf
> + LoadLinuxLib|$(BOARD_PKG)/Library/LoadLinuxLib/LoadLinuxLib.inf
> +
> CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/
> CpuExceptionHandlerLibNull.inf
> +
> +
> TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLibNull/TestPoi
> ntCheckLibNull.inf
> +
> BoardInitLib|MinPlatformPkg/PlatformInit/Library/BoardInitLibNull/BoardInitLi
> bNull.inf
> +
> SiliconPolicyInitLib|$(BOARD_PKG)/Policy/Library/SiliconPolicyInitLib/SiliconPol
> icyInitLib.inf
> +
> SiliconPolicyUpdateLib|$(BOARD_PKG)/Policy/Library/SiliconPolicyUpdateLib/S
> iliconPolicyUpdateLib.inf
> +
> PciSegmentInfoLib|MinPlatformPkg/Pci/Library/PciSegmentInfoLibSimple/PciS
> egmentInfoLibSimple.inf
> +
> + !include MinPlatformPkg/Include/Dsc/CorePeiLib.dsc
> +
> +
> S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScri
> ptLib.inf
> +
> AslUpdateLib|MinPlatformPkg/Acpi/Library/DxeAslUpdateLib/DxeAslUpdateLib.
> inf
> +[LibraryClasses.common.SEC]
> +
> ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExt
> ractGuidedSectionLib.inf
> +
> +[LibraryClasses.common.PEI_CORE]
> +
> +[LibraryClasses.common.PEIM]
> +
> PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiReso
> urcePublicationLib.inf
> + MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
> +
> +[LibraryClasses.IA32]
> +!if $(TARGET) == DEBUG
> +
> TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLib/PeiTestPoi
> ntCheckLib.inf
> +!endif
> + TestPointLib|MinPlatformPkg/Test/Library/TestPointLib/PeiTestPointLib.inf
> +
> + !include MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc
> +
> +[LibraryClasses.common.DXE_CORE]
> +
> +[LibraryClasses.common.DXE_RUNTIME_DRIVER]
> +
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> Ich10.inf
> +
> +[LibraryClasses.common.UEFI_DRIVER]
> +
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> Ich10.inf
> +
> +[LibraryClasses.common.DXE_DRIVER]
> +
> PlatformBootManagerLib|$(BOARD_PKG)/Overrides/MdeModulePkg/Library/P
> latformBootManagerLib/PlatformBootManagerLib.inf
> +
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> Ich10.inf
> +
> +[LibraryClasses.common.UEFI_APPLICATION]
> +
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> Ich10.inf
> +
> +[LibraryClasses.common.DXE_SMM_DRIVER]
> +
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> Ich10.inf
> +
> SpiFlashCommonLib|$(PCH_PKG)/Library/SmmSpiFlashCommonLib/SmmSpiFla
> shCommonLib.inf
> +
> +[LibraryClasses.common.SMM_CORE]
> +
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> Ich10.inf
> +
> + !include $(BOARD_PKG)/$(BOARD_NAME)/PlatformPkgPcd.dsc
> +
> +[Components.IA32]
> + !include $(SKT_PKG)/SktPei.dsc
> + !include MinPlatformPkg/Include/Dsc/CorePeiInclude.dsc
> +
> + $(BOARD_PKG)/PlatformPei/PlatformPei.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/PeiBoardI
> nitPreMemLib.inf
> + }
> + MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf {
> + <LibraryClasses>
> +
> BoardInitLib|$(BOARD_PKG)/$(BOARD_NAME)/Library/BoardInitLib/PeiBoardI
> nitPostMemLib.inf
> + }
> + MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf
> + MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf
> +
> +[Components.X64]
> + !include MinPlatformPkg/Include/Dsc/CoreDxeInclude.dsc
> +
> $(BOARD_PKG)/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.i
> nf
> + !include AdvancedFeaturePkg/Include/Dsc/CoreAdvancedDxeInclude.dsc
> +
> + MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
> + $(BOARD_PKG)/Overrides/MdeModulePkg/Logo/LogoDxe.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)/PlatformDxe/Platform.inf
> + MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
> +
> MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.
> inf
> +
> + #
> + # Shell
> + #
> + ShellPkg/Application/Shell/Shell.inf {
> + <PcdsFixedAtBuild>
> + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> + <LibraryClasses>
> +
> NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2Command
> sLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1Command
> sLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3Command
> sLib.inf
> +
> NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1Comman
> dsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1Co
> mmandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Co
> mmandsLib.inf
> +
> ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLi
> b.inf
> +
> HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.
> inf
> +
> BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCo
> mmandLib.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)/Overrides/MdeModulePkg/Library/PciHostBr
> idgeLib/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)/PlatformPkgBuildOption.dsc
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.f
> df
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.f
> df
> new file mode 100644
> index 0000000000..d6c381a515
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.f
> df
> @@ -0,0 +1,303 @@
> +## @file
> +#
> +# Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +!include SimicsX58Pkg.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|gEfi
> MdeModulePkgTokenSpaceGuid.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|gEfiMd
> eModulePkgTokenSpaceGuid.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
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase|gSimicsX58PkgT
> okenSpaceGuid.PcdSimicsSecPageTablesSize
> +
> +0x006000|0x001000
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase|gSimicsX58Pkg
> TokenSpaceGuid.PcdSimicsLockBoxStorageSize
> +
> +0x007000|0x001000
> +gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gSimicsX
> 58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> +
> +0x010000|0x008000
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|gSimicsX58Pk
> gTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> +
> +0x020000|0x0E0000
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase|gSimicsX58PkgToke
> nSpaceGuid.PcdSimicsPeiMemFvSize
> +FV = FvPreMemory
> +
> +0x100000|0xA00000
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase|gSimicsX58PkgTok
> enSpaceGuid.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
> +
> +!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)/PchPreMemoryInclude.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)/PlatformPei/PlatformPei.inf
> +!include $(SKT_PKG)/SktPostMemoryInclude.fdf
> +!include $(PCH_PKG)/PchPostMemoryInclude.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
> +INF
> $(BOARD_PKG)/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.i
> nf
> +!include $(SKT_PKG)/SktUefiBootInclude.fdf
> +!include $(PCH_PKG)/PchUefiBootInclude.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 $(BOARD_PKG)/Overrides/MdeModulePkg/Logo/LogoDxe.inf
> +INF MinPlatformPkg/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
> +INF MinPlatformPkg/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
> +INF $(BOARD_PKG)/PlatformDxe/Platform.inf
> +
> +INF ShellPkg/Application/Shell/Shell.inf
> +
> +#
> +# Network modules
> +#
> +FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 {
> + SECTION PE32 = SimicsICH10SiliconBinPkg/UndiBinary/GigUndiDxe.efi
> + SECTION UI = "IntelIch10UNDI"
> +}
> +!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/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|gEfiMde
> ModulePkgTokenSpaceGuid.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/bld.bat
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
> new file mode 100644
> index 0000000000..efce310dfe
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
> @@ -0,0 +1,139 @@
> +@echo off
> +@REM @file
> +@REM Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +@REM
> +@REM SPDX-License-Identifier: BSD-2-Clause-Patent
> +@REM
> +
> +@echo off
> +
> +REM Run setlocal to take a snapshot of the environment variables. endlocal is
> called to restore the environment.
> +setlocal
> +set SCRIPT_ERROR=0
> +
> +REM ---- Do NOT use :: for comments Inside of code blocks() ----
> +
> +::***********************************************************
> ***********
> +:: Initial Setup
> +::***********************************************************
> ***********
> +
> +:parseCmdLine
> +if "%1"=="" goto :argumentCheck
> +
> +if /I "%1"=="debug" set TARGET=DEBUG
> +if /I "%1"=="release" set TARGET=RELEASE
> +
> +if /I "%1"=="cleantree" (
> + set BUILD_TYPE=cleantree
> + call :cleantree
> + goto :EOF
> +)
> +
> +shift
> +GOTO :parseCmdLine
> +
> +:argumentCheck:
> +
> +if /I "%TARGET%" == "" (
> + echo Info: debug/release argument is empty, use DEBUG as default
> + set TARGET=DEBUG
> +)
> +
> +REM Art to notify which board you're working on
> +echo.
> +type logo.txt
> +echo.
> +
> +::
> +:: Build configuration
> +::
> +set BUILD_REPORT_FLAGS=
> +set BUILD_CMD_LINE=
> +set BUILD_LOG=%WORKSPACE%\Build\BuildSrc\build.log
> +set BUILD_REPORT=%WORKSPACE%\Build\BuildSrc\BuildReport.txt
> +
> +del %BUILD_LOG% *.efi *.log 2>NUL
> +
> +echo --------------------------------------------------------------------------------------------
> +echo.
> +echo QSP Build Start
> +echo.
> +echo --------------------------------------------------------------------------------------------
> +
> +
> +:doPreBuild
> +echo.
> +echo --------------------------------------------------------------------
> +echo.
> +echo Prebuild Start
> +echo.
> +echo --------------------------------------------------------------------
> +call prebuild.bat
> +if %SCRIPT_ERROR% NEQ 0 EXIT /b %ERRORLEVEL%
> +
> +echo --------------------------------------------------------------------
> +echo.
> +echo Prebuild End
> +echo.
> +echo --------------------------------------------------------------------
> +if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
> +timeout 1
> +
> +:buildBios
> +set BUILD_CMD_LINE=%BUILD_CMD_LINE% -D
> MAX_SOCKET=%MAX_SOCKET% -y %BUILD_REPORT%
> +echo --------------------------------------------------------------------
> +echo.
> +echo Build Start
> +echo.
> +echo --------------------------------------------------------------------
> +echo.
> +echo build %BUILD_CMD_LINE% --log=%BUILD_LOG%
> %BUILD_REPORT_FLAGS%
> +call build %BUILD_CMD_LINE% --log=%BUILD_LOG%
> %BUILD_REPORT_FLAGS%
> +echo --------------------------------------------------------------------
> +echo.
> +echo Build End
> +echo.
> +echo --------------------------------------------------------------------
> +if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
> +timeout 1
> +
> +:postBuild
> +
> +echo --------------------------------------------------------------------
> +echo.
> +echo PostBuild Start
> +echo.
> +echo --------------------------------------------------------------------
> +echo.
> +REM call postbuild.bat
> +if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
> +timeout 1
> +echo --------------------------------------------------------------------
> +echo.
> +echo PostBuild End
> +echo.
> +echo --------------------------------------------------------------------
> +
> +echo %date% %time%
> +echo.
> +
> +echo --------------------------------------------------------------------------------------------
> +echo.
> +echo QSP Build End
> +echo.
> +echo --------------------------------------------------------------------------------------------
> +
> +:done
> +endlocal & EXIT /b %SCRIPT_ERROR%
> +
> +::--------------------------------------------------------
> +::-- Function section starts below here
> +::--------------------------------------------------------
> +:cleantree
> +choice /t 3 /d y /m "Confirm: clean tree of intermediate files created in tree
> during build"
> +if %ERRORLEVEL% EQU 2 goto :EOF
> +goto :EOF
> +
> +
> +:ErrorHandler:
> +echo Error handler
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
> new file mode 100644
> index 0000000000..ad3ae229e8
> --- /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 = WORKSPACE_PLATFORM_BIN
> +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/SimicsX58PkgIa32X64.dsc
> +BOARD_PKG_PCD_DSC =
> SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.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
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
> new file mode 100644
> index 0000000000..666332e2d4
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
> @@ -0,0 +1,198 @@
> +@echo off
> +@REM @file
> +@REM Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +@REM
> +@REM SPDX-License-Identifier: BSD-2-Clause-Patent
> +@REM
> +
> +@set SCRIPT_ERROR=0
> +
> +set /a prebuildstep=0
> +
> +call :check_BuildTools
> +if %SCRIPT_ERROR% NEQ 0 GOTO :done
> +
> +call :setBuildEnv
> +if %SCRIPT_ERROR% NEQ 0 GOTO :done
> +
> +call :createTargetTxt
> +if %SCRIPT_ERROR% NEQ 0 GOTO :done
> +
> +REM call :genPlatformOffsetHeaderFile
> +REM if %SCRIPT_ERROR% NEQ 0 GOTO :done
> +
> +:prebuildFinish
> +echo.
> +echo ACTIVE_PLATFORM = %WORKSPACE%\edk2-
> platforms\Platform\Intel\%BOARD_PKG%\%BOARD_NAME%\SimicsX58PkgIa3
> 2X64.dsc
> +echo EDK_TOOLS_PATH = %EDK_TOOLS_PATH%
> +echo TARGET = %TARGET%
> +echo TARGET_ARCH = IA32 X64
> +echo TOOL_CHAIN_TAG = %TOOL_CHAIN_TAG%
> +echo WORKSPACE = %WORKSPACE%
> +echo PACKAGES_PATH = %PACKAGES_PATH%
> +echo MAX_CONCURRENT_THREAD_NUMBER =
> %BUILD_MAX_CON_THREAD_NUM%
> +echo.
> +echo Build Path = %OUTPUT_DIR%
> +echo.
> +
> +REM Remove environment variable because it's no longer needed.
> +set BUILD_MAX_CON_THREAD_NUM=
> +
> +:done
> +REM Use done label to exit batch file and run any final steps; GOTO :EOF
> immediately exits.
> +EXIT /B %SCRIPT_ERROR%
> +
> +::--------------------------------------------------------
> +::-- Function section starts below here
> +::--------------------------------------------------------
> +
> +:cleanup_check_VSTools
> +set COMPILER_VERSION_STRING=
> +del cloutput.txt > nul
> +REM cleanup_check_VSTools is called below. When a label is called, 'GOTO
> :EOF' is used to return to caller.
> +GOTO :EOF
> +
> +:check_BuildTools
> +echo PreBuild.%prebuildstep% check_BuildTools
> +echo ..VSTools
> +set /a prebuildstep=%prebuildstep%+1
> +set TOOL_CHAIN_TAG=
> +@if not defined TOOL_CHAIN_TAG (
> + echo.
> + echo Prebuild: TOOL_CHAIN_TAG is not set before
> + echo.
> +
> + @if defined VS140COMNTOOLS (
> + echo.
> + echo Set the VS2015 environment.
> + echo.
> + set CL_SEL=VS2015
> + if /I "%VS140COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio
> 14.0\Common7\Tools\" (
> + set TOOL_CHAIN_TAG=VS2015
> + ) else (
> + set TOOL_CHAIN_TAG=VS2015x86
> + )
> + if /I "%PROCESSOR_ARCHITECTURE%" == "AMD64" (
> + set CL_CMDLINE="%VS140COMNTOOLS:~0,-14%VC\bin\amd64\cl.exe"
> + ) else (
> + set CL_CMDLINE="%VS140COMNTOOLS:~0,-14%VC\bin\cl.exe"
> + )
> + ) else if defined VS120COMNTOOLS (
> + echo.
> + echo Set the VS2013 environment.
> + echo.
> + set CL_SEL=VS2013
> + if /I "%VS120COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio
> 12.0\Common7\Tools\" (
> + set TOOL_CHAIN_TAG=VS2013
> + ) else (
> + set TOOL_CHAIN_TAG=VS2013x86
> + )
> + if /I "%PROCESSOR_ARCHITECTURE%" == "AMD64" (
> + set CL_CMDLINE="%VS120COMNTOOLS:~0,-14%VC\bin\amd64\cl.exe"
> + ) else (
> + set CL_CMDLINE="%VS120COMNTOOLS:~0,-14%VC\bin\cl.exe"
> + )
> + ) else (
> + echo.
> + echo !!! ERROR !!! VS2015 or VS2013 not installed correctly. !!!
> + echo.
> + goto :ErrorExit
> + )
> +)
> +
> +echo ..iASL
> +set CHECK_PATH_IASL=%IASL_PREFIX%
> +if not exist %CHECK_PATH_IASL%\iasl.exe (
> + echo.
> + echo !!! ERROR !!! Could not find iASL compiler at
> %CHECK_PATH_IASL%\iasl.exe. !!!
> + echo.
> + set SCRIPT_ERROR=1
> +)
> +set CHECK_PATH_IASL=
> +
> +echo ..NASM
> +set CHECK_PATH_NASM=c:\NASM
> +if not exist %CHECK_PATH_NASM%\nasm.exe (
> + echo.
> + echo !!! ERROR !!! Could not find NASM compiler at
> %CHECK_PATH_NASM%\nasm.exe. !!!
> + echo.
> + set SCRIPT_ERROR=1
> +)
> +set CHECK_PATH_NASM=
> +
> +echo ..Python
> +set CHECK_PATH_PYTHON=c:\Python27
> +if not exist %CHECK_PATH_PYTHON%\python.exe (
> + echo.
> + echo !!! ERROR !!! Could not find Python at
> %CHECK_PATH_PYTHON%\python.exe. !!!
> + echo.
> + set SCRIPT_ERROR=1
> +)
> +set CHECK_PATH_PYTHON=
> +set PYTHON_HOME=C:\Python27
> +
> +GOTO :EOF
> +
> +:setBuildEnv
> +echo PreBuild.%prebuildstep% SetBuildEnv
> +set /a prebuildstep=%prebuildstep%+1
> +
> +@set BOARD_PKG=SimicsOpenBoardPkg
> +@set BOARD_NAME=BoardX58ICH10
> +@set MAX_SOCKET=2
> +
> +echo.
> +echo BOARD_NAME=%BOARD_NAME%
> +echo BOARD_PKG=%BOARD_PKG%
> +echo MAX_SOCKET=%MAX_SOCKET%
> +echo TARGET=%TARGET%
> +
> +@set
> OUTPUT_DIR=%WORKSPACE%\Build\BuildSrc\%BOARD_PKG%\%BOARD_NAM
> E%\%TARGET%_%TOOL_CHAIN_TAG%
> +
> +if not exist %OUTPUT_DIR% mkdir %OUTPUT_DIR%
> +GOTO :EOF
> +
> +:createTargetTxt
> +echo PreBuild.%prebuildstep% CreateTargetTxt
> +set /a prebuildstep=%prebuildstep%+1
> +set /a BUILD_MAX_CON_THREAD_NUM = %NUMBER_OF_PROCESSORS%-1
> +@REM set /a BUILD_MAX_CON_THREAD_NUM = 1
> +findstr /V "ACTIVE_PLATFORM TARGET TARGET_ARCH TOOL_CHAIN_TAG
> BUILD_RULE_CONF MAX_CONCURRENT_THREAD_NUMBER"
> %WORKSPACE%\Conf\target.txt > %OUTPUT_DIR%\target.txt 2>NUL
> +echo ACTIVE_PLATFORM = %WORKSPACE%/edk2-
> platforms/Platform/Intel/%BOARD_PKG%/%BOARD_NAME%/SimicsX58PkgIa3
> 2X64.dsc >> %OUTPUT_DIR%\target.txt
> +echo TARGET = %TARGET% >>
> %OUTPUT_DIR%\target.txt
> +echo TARGET_ARCH = IA32 X64 >>
> %OUTPUT_DIR%\target.txt
> +echo TOOL_CHAIN_TAG = %TOOL_CHAIN_TAG% >>
> %OUTPUT_DIR%\target.txt
> +echo BUILD_RULE_CONF = Conf/build_rule.txt >>
> %OUTPUT_DIR%\target.txt
> +echo MAX_CONCURRENT_THREAD_NUMBER =
> %BUILD_MAX_CON_THREAD_NUM% >> %OUTPUT_DIR%\target.txt
> +if exist %WORKSPACE%\Conf\target.txt (
> + del /f %WORKSPACE%\Conf\target.txt
> +)
> +move /Y %OUTPUT_DIR%\target.txt %WORKSPACE%\Conf\ > nul
> +if not exist %OUTPUT_DIR%\X64 mkdir %OUTPUT_DIR%\X64
> +GOTO :EOF
> +
> +
> +:genPlatformOffsetHeaderFile
> +echo.
> +echo PreBuild.%prebuildstep% GenPlatformOffsetHeaderFile
> +set /a prebuildstep=%prebuildstep%+1
> +
> +echo Info: re-generating PlatformOffset header files
> +
> +set PRE_BUILD_CMD_LINE=%BUILD_CMD_LINE% -D
> MAX_SOCKET=%MAX_SOCKET%
> +set PRE_BUILD_LOG=%WORKSPACE%\Build\BuildSrc\prebuild.log
> +set PRE_BUILD_REPORT=%WORKSPACE%\Build\BuildSrc\preBuildReport.txt
> +
> +echo build %PRE_BUILD_CMD_LINE% -m
> %BOARD_PKG%\Acpi\BoardAcpiDxe\Dsdt.inf -y %PRE_BUILD_REPORT% --
> log=%PRE_BUILD_LOG%
> +call build %PRE_BUILD_CMD_LINE% -m
> %BOARD_PKG%\Acpi\BoardAcpiDxe\Dsdt.inf -y %PRE_BUILD_REPORT% --
> log=%PRE_BUILD_LOG%
> +if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
> +
> +@REM PSYS == FIX0
> +@REM MCTL == FIX8
> +set AML_FILTER="\"PSYS\" .MCTL\" .FIX[0-9,A-Z]\""
> +echo AML_FILTER=%AML_FILTER%
> +%WORKSPACE%\edk2-
> platforms\Platform\Intel\MinPlatformPkg\Tools\AmlGenOffset\AmlGenOffset.
> py -d --aml_filter %AML_FILTER% -o %WORKSPACE%\edk2-
> platforms\Platform\Intel\%BOARD_PKG%\Acpi\BoardAcpiDxe\AmlOffsetTable.
> c
> %OUTPUT_DIR%\X64\PurleyOpenBoardPkg\Acpi\BoardAcpiDxe\DSDT\OUTPU
> T\Dsdt\WFPPlatform.offset.h
> +echo.
> +echo GenOffset done
> +
> +GOTO :EOF
> --
> 2.16.2.windows.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform
2019-08-09 22:46 ` [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform David Wei
2019-08-15 19:28 ` Nate DeSimone
2019-08-19 23:21 ` Nate DeSimone
@ 2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 17:06 ` David Wei
2 siblings, 1 reply; 37+ messages in thread
From: Kubacki, Michael A @ 2019-08-20 1:04 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
You will need to resolve a conflict in build.cfg. When you do so, please keep the boards under
[PLATFORMS] in lexicographically ascending order for ease of maintenance.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 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-platform patch 7/7] Platform/Intel: Add build option for SIMICS
> QSP Platform
>
> Add build option in build script for SIMICS QSP Platform
>
> 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
> Platform/Intel/build.cfg | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg index
> fc6e4fe824..2ebe09a632 100644
> --- a/Platform/Intel/build.cfg
> +++ b/Platform/Intel/build.cfg
> @@ -54,3 +54,5 @@ NUMBER_OF_PROCESSORS = 0
> KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
> N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
> BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
> +WhiskeylakeURvp =
> +WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
> +BoardX58ICH10 = SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
> --
> 2.16.2.windows.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
2019-08-20 1:04 ` Kubacki, Michael A
@ 2019-08-22 22:31 ` David Wei
2019-08-26 22:48 ` Kubacki, Michael A
0 siblings, 1 reply; 37+ messages in thread
From: David Wei @ 2019-08-22 22:31 UTC (permalink / raw)
To: Kubacki, Michael A, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Hi Mike,
Please see the updates online below. Please let me know if you have any more comments.
Thanks
David
-----Original Message-----
From: Kubacki, Michael A
Sent: Monday, August 19, 2019 6:04 PM
To: Wei, David Y <david.y.wei@intel.com>; 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>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: RE: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
Feedback I could not find already noted elsewhere:
1. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c:
There's some style issues throughout the file related to a missing space before opening parenthesis and parameters than span multiple lines.
Some of these are pre-existing in OvmfPkg source. I don't think this is a must have.
Ydwei: done
2. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 265:
"Confirm if QEMU supports SMRAM." to "Confirm if Simics supports SMRAM."
Ydwei: done
3. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 275:
"DEBUG((EFI_D_ERROR, "TopOfLowRam =0x%x; TopOfLowRamMb =0x%x \n", TopOfLowRam, TopOfLowRamMb));"
Should be an informational message.
Ydwei: done
3. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 283:
"DEBUG((EFI_D_ERROR, "MCH_TOLUD =0x%x; \n", PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD))));"
Should be an informational message.
Ydwei: done
4. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 300 & Line 301 - Should be informational messages as well.
Ydwei: done
5. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf: Is a dependency on OvmfPkg/OvmfPkg.dec required? This dependency should be avoided.
Ydwei: done
6. Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore: I don't think this should be an override but should exist in a similar manner
as edk2/OvmfPkg/Sec. The code cannot be upstreamed as-is.
Ydwei: done
7. /Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c: Some of this messages should probably be verbose not informational.
Ydwei: done
8. /Silicon/Intel/SimicsX58SktPkg/SktPei.dsc: This file naming convention is unusual. SktPkgPei.dsc is more consistent.
Ydwei: done
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 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-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for
> SimicsX58
>
> 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
> .../Override/UefiCpuPkg/SecCore/SecMain.c | 956
> +++++++++++++++++++++
> .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c | 148 ++++
> .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c | 353 ++++++++
> .../SimicsX58SktPkg/Smm/Access/SmramInternal.c | 199 +++++
> .../Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm | 45 +
> .../Override/UefiCpuPkg/SecCore/SecMain.inf | 71 ++
> .../Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm | 45 +
> Silicon/Intel/SimicsX58SktPkg/SktPei.dsc | 18 +
> .../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf | 9 +
> .../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf | 10 +
> Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf | 17 +
> .../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf | 16 +
> .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf | 52 ++
> .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf | 64 ++
> .../SimicsX58SktPkg/Smm/Access/SmramInternal.h | 81 ++
> 15 files changed, 2084 insertions(+)
> create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.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
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nas
> m
> create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> create mode 100644
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.nas
> m
> create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPei.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/Override/UefiCpuPkg/SecCore/SecMain.c
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
> new file mode 100644
> index 0000000000..c52d459ef2
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/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 <IndustryStandard/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_INFO, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32
> (PcdSimicsDxeMemFvBase)));
> + DEBUG ((EFI_D_INFO, "OutputBuffer: 0x%x\n", OutputBuffer));
> + DEBUG ((EFI_D_INFO, "OutputBufferSize: 0x%x\n", OutputBufferSize));
> + DEBUG ((EFI_D_INFO, "ScratchBuffer: 0x%x\n", ScratchBuffer));
> + DEBUG ((EFI_D_INFO, "ScratchBufferSize: 0x%x\n", ScratchBufferSize));
> + DEBUG ((EFI_D_INFO, "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_ERROR, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "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/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..d07d88142a
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> @@ -0,0 +1,353 @@
> +/** @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, 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 <SimicsPlatforms.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 QEMU 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 QEMU.
> + //
> +
> + TopOfLowRam = GetSystemMemorySizeBelow4gb ();
> + ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) == 0);
> + TopOfLowRamMb = TopOfLowRam >> 20;
> + DEBUG((EFI_D_ERROR, "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_ERROR, "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_ERROR, "MCH_TSEGMB =0x%x; \n",
> PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
> + DEBUG((EFI_D_ERROR, "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..898fc25084
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> @@ -0,0 +1,199 @@
> +/** @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 <Guid/AcpiS3Context.h>
> +#include <IndustryStandard/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/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.n
> asm
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.
> nasm
> new file mode 100644
> index 0000000000..19ffb6f86d
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.
> nasm
> @@ -0,0 +1,45 @@
> +; @file
> +; Copyright (c) 2006 - 2013 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/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> new file mode 100644
> index 0000000000..ac993ac1ce
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> @@ -0,0 +1,71 @@
> +## @file
> +# SEC Driver
> +#
> +# Copyright (c) 2008 - 2018 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
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + BaseMemoryLib
> + PeiServicesLib
> + PcdLib
> + UefiCpuLib
> + DebugAgentLib
> + IoLib
> + PeCoffLib
> + PeCoffGetEntryPointLib
> + PeCoffExtraActionLib
> + ExtractGuidedSectionLib
> + LocalApicLib
> + PciCf8Lib
> +
> +[Ppis]
> + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
> +
> +[Pcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> + gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> +
> +[FeaturePcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> diff --git
> a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> asm
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> asm
> new file mode 100644
> index 0000000000..0eb86ec2ca
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> asm
> @@ -0,0 +1,45 @@
> +; @file
> +; Copyright (c) 2006 - 2013 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/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> new file mode 100644
> index 0000000000..0be8be4966
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> @@ -0,0 +1,18 @@
> +## @file
> +# Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> + #
> + # SEC Phase modules
> + #
> + $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf {
> + <LibraryClasses>
> +
> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecom
> pressLib.inf
> + }
> + 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..78eca21a43
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> @@ -0,0 +1,9 @@
> +## @file
> +# Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2017 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..9f037e99d4
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> @@ -0,0 +1,10 @@
> +## @file
> +# Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 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..596d633cd3
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> @@ -0,0 +1,17 @@
> +## @file
> +# Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 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_SECMAIN USE = IA32
> $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf
> +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..9004b9cb83
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> @@ -0,0 +1,16 @@
> +## @file
> +# Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +#INF $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuArchDxe/CpuArchDxe.inf
> +#INF $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuMpDxe/CpuMpDxe.inf
> +!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..2f630b4b95
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> @@ -0,0 +1,52 @@
> +## @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.
> +#
> +# 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
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..1d3b028c85
> --- /dev/null
> +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> @@ -0,0 +1,64 @@
> +## @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.
> +#
> +# 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
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> + OvmfPkg/OvmfPkg.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 [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10
2019-08-20 1:04 ` Kubacki, Michael A
@ 2019-08-23 16:40 ` David Wei
2019-08-26 22:49 ` Kubacki, Michael A
0 siblings, 1 reply; 37+ messages in thread
From: David Wei @ 2019-08-23 16:40 UTC (permalink / raw)
To: Kubacki, Michael A, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Hi Mike,
Please see the updates online below. Please let me know if you have any more comments.
Thanks
David
-----Original Message-----
From: Kubacki, Michael A
Sent: Monday, August 19, 2019 6:04 PM
To: Wei, David Y <david.y.wei@intel.com>; 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>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: RE: [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10
Feedback I could not find already noted elsewhere:
1. /Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf:
This silicon package should not have a dependency on MinPlatformPkg.dec.
Ydwei: done
2. /Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpiCommonLib.inf:
This silicon package should not have a dependency on SimicsOpenBoardPkg.dec.
Ydwei: done
3. Although noted elsewhere: I also prefer Pascal naming as well so SimicsIch10Pkg.
Ydwei: done
4. /Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.c:
"Reset System Library functions for OVMF" - replace OVMF with Simics ICH10.
Ydwei: done
5. /Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.inf:
This silicon package INF should not have a dependency on MinPlatformPkg.dec.
Ydwei: done
6. /Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
This silicon package INF should not have a dependency on MinPlatformPkg.dec.
Ydwei: done
7. /Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonib/SmmSpiFlashCommonLib:
This silicon package INF should not have a dependency on MinPlatformPkg.dec.
Ydwei: done
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 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-platform patch 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> 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 | 22 +
> .../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 +++++++
> .../IncludePrivate/Library/PchSpiCommonLib.h | 396 +++++++++
> .../Library/ResetSystemLib/ResetSystemLib.inf | 34 +
> .../SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf | 52 ++
> .../BasePchSpiCommonLib/BasePchSpiCommonLib.inf | 33 +
> Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc | 12 +
> .../Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf | 9 +
> .../Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf | 9 +
> .../Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf | 13 +
> .../SmmControl/RuntimeDxe/SmmControl2Dxe.inf | 59 ++
> Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpi.h | 23 +
> Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpiSmm.inf | 44 +
> 25 files changed, 4152 insertions(+)
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.c
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommo
> n.c
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCommo
> nSmmLib.c
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCommo
> n.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/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/IncludePrivate/Library/PchSpiCommonLib.h
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.inf
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlashCo
> mmonLib.inf
> create mode 100644
> Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePchSpi
> CommonLib.inf
> create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
> create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
> create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
> create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
> 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..46355e191c
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.c
> @@ -0,0 +1,137 @@
> +/** @file
> + Reset System Library functions for OVMF
> +
> + Copyright (c) 2006 - 2016 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 <IndustryStandard/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/SpiFlashCom
> mon.c
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCom
> mon.c
> new file mode 100644
> index 0000000000..3d4e24eac6
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCom
> mon.c
> @@ -0,0 +1,194 @@
> +/** @file
> + Wrap EFI_SPI_PROTOCOL to provide some library level interfaces
> + for module use.
> +
> + Copyright (c) 2017 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/SpiFlashCom
> monSmmLib.c
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCom
> monSmmLib.c
> new file mode 100644
> index 0000000000..1e5cd0d744
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCom
> monSmmLib.c
> @@ -0,0 +1,54 @@
> +/** @file
> + SMM Library instance of SPI Flash Common Library Class
> +
> + Copyright (c) 2017 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/SpiCom
> mon.c
> b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCom
> mon.c
> new file mode 100644
> index 0000000000..77fb76d7cd
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCom
> mon.c
> @@ -0,0 +1,935 @@
> +/** @file
> + PCH SPI Common Driver implements the SPI Host Controller Compatibility
> Interface.
> +
> + Copyright (c) 2017 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 <IndustryStandard/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..8fb4947b1a
> --- /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 - 2010, Intel Corporation. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <IndustryStandard/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..19eb469657
> --- /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) 2017 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..f9d340d6df
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/ICH10Pkg.dec
> @@ -0,0 +1,22 @@
> +## @file
> +# Copyright (c) 2014 - 2016 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}}
> diff --git a/Silicon/Intel/SimicsICH10Pkg/Include/Library/SpiFlashCommonLib.h
> b/Silicon/Intel/SimicsICH10Pkg/Include/Library/SpiFlashCommonLib.h
> new file mode 100644
> index 0000000000..c36360bcb0
> --- /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) 2017 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..552ce28d8c
> --- /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) 2017 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..d503d130c8
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/Include/PchLimits.h
> @@ -0,0 +1,94 @@
> +/** @file
> + Build time limits of PCH resources.
> +
> + Copyright (c) 2017 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..00139fc230
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/Include/PchReservedResources.h
> @@ -0,0 +1,60 @@
> +/** @file
> + PCH preserved MMIO resource definitions.
> +
> + Copyright (c) 2017 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..cb5f26c47b
> --- /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) 2017 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..e08721f405
> --- /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) 2017 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..a727aae927
> --- /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) 2017 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/IncludePrivate/Library/PchSpiCommonLib.h
> b/Silicon/Intel/SimicsICH10Pkg/IncludePrivate/Library/PchSpiCommonLib.h
> new file mode 100644
> index 0000000000..5bdec96197
> --- /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) 2017 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..4af462da47
> --- /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 - 2018 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
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> + DebugLib
> + IoLib
> + TimerLib
> diff --git
> a/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlash
> CommonLib.inf
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlash
> CommonLib.inf
> new file mode 100644
> index 0000000000..b5c97f1930
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlash
> CommonLib.inf
> @@ -0,0 +1,52 @@
> +## @file
> +# SMM Library instance of Spi Flash Common Library Class
> +#
> +# Copyright (c) 2017 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
> + MinPlatformPkg/MinPlatformPkg.dec
> +
> +
> +[Pcd]
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
> +
> +[Sources]
> + SpiFlashCommonSmmLib.c
> + SpiFlashCommon.c
> +
> +[Protocols]
> + gEfiSmmSpiProtocolGuid ## CONSUMES
> +
> +[Depex.X64.DXE_SMM_DRIVER]
> + gEfiSmmSpiProtocolGuid
> diff --git
> a/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePch
> SpiCommonLib.inf
> b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePch
> SpiCommonLib.inf
> new file mode 100644
> index 0000000000..11c832e487
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePch
> SpiCommonLib.inf
> @@ -0,0 +1,33 @@
> +## @file
> +# Component description file for the PchSpiCommonLib
> +#
> +# Copyright (c) 2017 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
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> + MinPlatformPkg/MinPlatformPkg.dec
> +
> +[LibraryClasses]
> + IoLib
> + DebugLib
> +
> +[Pcd]
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## CONSUMES
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
> diff --git a/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
> b/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
> new file mode 100644
> index 0000000000..a2d006ee35
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
> @@ -0,0 +1,12 @@
> +## @file
> +# Component description file for the SkyLake SiPkg DXE libraries.
> +#
> +# Copyright (c) 2017 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/BasePc
> hSpiCommonLib.inf
> diff --git a/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
> b/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
> new file mode 100644
> index 0000000000..78eca21a43
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
> @@ -0,0 +1,9 @@
> +## @file
> +# Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> diff --git a/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
> b/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
> new file mode 100644
> index 0000000000..2d3a127c20
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
> @@ -0,0 +1,9 @@
> +## @file
> +# Component description file for the SkyLake SiPkg PEI drivers.
> +#
> +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> diff --git a/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
> b/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
> new file mode 100644
> index 0000000000..d079c593d9
> --- /dev/null
> +++ b/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
> @@ -0,0 +1,13 @@
> +## @file
> +# Component description file for the SkyLake SiPkg DXE drivers.
> +#
> +# Copyright (c) 2017 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/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
> b/Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
> new file mode 100644
> index 0000000000..e23dd9f2fe
> --- /dev/null
> +++
> b/Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
> @@ -0,0 +1,59 @@
> +## @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.
> +#
> +# 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
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..f7fdd3abbe
> --- /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) 2017 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..265af00ac0
> --- /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) 2017 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 [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
2019-08-20 1:04 ` Kubacki, Michael A
@ 2019-08-23 16:57 ` David Wei
2019-08-26 23:13 ` Kubacki, Michael A
0 siblings, 1 reply; 37+ messages in thread
From: David Wei @ 2019-08-23 16:57 UTC (permalink / raw)
To: Kubacki, Michael A, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Hi Mike,
Please see the updates online below. Please let me know if you have any more comments.
Thanks
David
-----Original Message-----
From: Kubacki, Michael A
Sent: Monday, August 19, 2019 6:04 PM
To: Wei, David Y <david.y.wei@intel.com>; 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>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: RE: [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
Feedback I could not find already covered elsewhere:
1. Dsdt.asl: Change "OVMF" in the following line to something else unique to this implementation:
"DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF ", 4) {"
Ydwei: done
2. BasePchSpiCommonLib.inf: This silicon package should not have a dependency on SimicsOpenBoardPkg.dec.
Ydwei: done
3. Platform.h: This header guard definition is unusual in style and convention, please correct: "_Platform_h_INCLUDED_"
Ydwei: done
4. Platform.h: Please update usage of "OVMF" in various signatures throughout the file to something package unique.
Ydwei: done
5. SimicsX58PlatformConfig.h: Why is this file not in SimicsX58SktPkg?
Ydwei: done
6. SimicsX58PlatformConfig.h: Change "OVMF" in copyright header to "Simics X58"
Ydwei: done
7. SimicsPlatforms.h: Change "OVMF" in copyright header to "Simics"
Ydwei: done
8. SimicsPlatforms.h - Line 16: Follow up on TODO
Ydwei: done
9. X58Ich10.h: Why is this file in the Simics board package? It should be in the silicon package.
Ydwei: done
10. LoadLinuxLib.inf: This package should avoid a depdency on OvmfPkg.dec
Ydwei: done
11. LoadLinuxLib.inf: Library name does not following naming convention. I.e. should be BaseLoadLinuxLib.inf.
Ydwei: This driver is from edk2\OvmfPkg\Library\LoadLinuxLib. I didn't make change.
12. LoadLinuxLib.inf: This is not truly a BASE library. For example, gBS (boot services) are unavailable in Runtime DXE.
Ydwei: This driver is from edk2\OvmfPkg\Library\LoadLinuxLib. I think it is just used by Linux Loader.
13. Platform.c: Change "OVMF" reference in copyright header.
Ydwei: done
14. Platform.h: Change "OVMF" reference in copyright header.
Ydwei: done
15. Cmos.c: It seems CmosAccessLib in BoardModulePkg could be used here to avoid duplication.
Ydwei: I tried CmosAccessLib in BoardModulePkg and it cause build error. I didn't make change.
16. Fv.c: In MinPlatform, a more intuitive place to manage FVs is in a board-specific instance of PeiReportFvLib
Ydwei: It is used for SIMICS S3 resume. Different purpose.
17. General comment: The modules "PlatformPei" and "PlatformDxe" should be avoided in a MinPlatform.
MinPlatformPkg is considered the "platform" and SimicsOpenBoardPkg is considered the "board", therefore this
code should likely be in a board library linked against a PlatformInit module in MinPlatformPkg. Such as BoardInitLib
which is very empty at the moment. At a minimum, if kept as a module for dispatch, the name should not lead to confusion
with platform modules in MinPlatformPkg.
Ydwei: They are SIMICS specifical. So I change their name as SimicsPei and SimicsDxe
18. PlatformPei.inf: This package should avoid a depdency on OvmfPkg.dec
Ydwei: done
19. X58SmamSaveStateMap.h: If X58-specific, it should go to SimicsX58SktPkg.
Ydwei: done
20. SerializeVariablesLib.inf: This package should avoid a depdency on OvmfPkg.dec
Ydwei: done
21. SimicsOpenBoardPkg.dec: Pcds in the gSimicsX58PkgTokenSpaceGuid token space should be declared in a DEC file
in the SimicsX58SktPkg. SimicsOpenBoardPkg should not be hardcoded to this particular silicon design.
Ydwei: done
22. SimicsOpenBoardPkg.dec: "X58" should be removed from the copyright header as the DEC is at the package-level
and not the board level.
Ydwei: done
23. SimicsOpenBoardPkg.dec: The PACKAGE_NAME should not be " SimicsX58Pkg" as the DEC is at package-level and
not Simics board-specific.
Ydwei: done
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 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-platform patch 3/7] SimicsOpenBoardPkg: Add
> SimicsOpenBoardPkg and its modules
>
> Add modules AcpiTables, Include, Library, PlatformDxe, PlatformPei, Policy,
> SmbiosPlatformDxe
> 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
> .../Library/LoadLinuxLib/Linux.c | 662 ++++++++++++++++
> .../Library/LoadLinuxLib/LinuxGdt.c | 175 +++++
> .../Library/NvVarsFileLib/FsAccess.c | 507 ++++++++++++
> .../Library/NvVarsFileLib/NvVarsFileLib.c | 77 ++
> .../SerializeVariablesLib/SerializeVariablesLib.c | 869
> +++++++++++++++++++++
> .../SimicsOpenBoardPkg/PlatformDxe/Platform.c | 865
> ++++++++++++++++++++
> .../PlatformDxe/PlatformConfig.c | 123 +++
> .../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c | 57 ++
> .../PlatformPei/FeatureControl.c | 114 +++
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c | 100 +++
> .../SimicsOpenBoardPkg/PlatformPei/MemDetect.c | 568 ++++++++++++++
> .../SimicsOpenBoardPkg/PlatformPei/Platform.c | 631 +++++++++++++++
> .../SiliconPolicyInitLib/SiliconPolicyInitLib.c | 108 +++
> .../SiliconPolicyUpdateLib.c | 70 ++
> .../SmbiosPlatformDxe/SmbiosPlatformDxe.c | 148 ++++
> .../SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf | 31 +
> .../Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl | 821
> +++++++++++++++++++
> .../Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h | 75 ++
> .../Include/Guid/SimicsX58PlatformConfig.h | 17 +
> .../Include/IndustryStandard/X58Ich10.h | 106 +++
> .../SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h | 298 +++++++
> .../SimicsOpenBoardPkg/Include/Protocol/IsaIo.h | 356 +++++++++
> .../Include/Protocol/Legacy8259.h | 291 +++++++
> .../Include/Register/X58SmramSaveStateMap.h | 178 +++++
> .../SimicsOpenBoardPkg/Include/SimicsPlatforms.h | 54 ++
> .../Library/LoadLinuxLib/Ia32/JumpToKernel.nasm | 41 +
> .../Library/LoadLinuxLib/LoadLinuxLib.h | 52 ++
> .../Library/LoadLinuxLib/LoadLinuxLib.inf | 42 +
> .../Library/LoadLinuxLib/X64/JumpToKernel.nasm | 85 ++
> .../Library/NvVarsFileLib/NvVarsFileLib.h | 55 ++
> .../Library/NvVarsFileLib/NvVarsFileLib.inf | 53 ++
> .../SerializeVariablesLib/SerializeVariablesLib.h | 33 +
> .../SerializeVariablesLib.inf | 36 +
> .../SimicsOpenBoardPkg/PlatformDxe/Platform.h | 37 +
> .../SimicsOpenBoardPkg/PlatformDxe/Platform.inf | 65 ++
> .../SimicsOpenBoardPkg/PlatformDxe/Platform.uni | 31 +
> .../PlatformDxe/PlatformConfig.h | 51 ++
> .../PlatformDxe/PlatformForms.vfr | 67 ++
> .../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h | 50 ++
> .../SimicsOpenBoardPkg/PlatformPei/Platform.h | 93 +++
> .../SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf | 109 +++
> .../SiliconPolicyInitLib/SiliconPolicyInitLib.inf | 38 +
> .../SiliconPolicyUpdateLib.inf | 35 +
> .../SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec | 168 ++++
> .../SmbiosPlatformDxe/SmbiosPlatformDxe.h | 38 +
> .../SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 51 ++
> 46 files changed, 8531 insertions(+)
> 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/SerializeVariablesLib/SerializeVaria
> blesLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconP
> olicyInitLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Silic
> onPolicyUpdateLib.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/SimicsX58PlatformConfig.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap
> .h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> 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/LoadLinuxLib.inf
> 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/SerializeVariablesLib/SerializeVaria
> blesLib.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVaria
> blesLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
> create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconP
> olicyInitLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Silic
> onPolicyUpdateLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.i
> nf
>
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> new file mode 100644
> index 0000000000..43a2dee9f6
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> @@ -0,0 +1,662 @@
> +/** @file
> + Copyright (c) 2011 - 2014 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..624fbc37cb
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
> @@ -0,0 +1,175 @@
> +/** @file
> + Initialize GDT for Linux.
> +
> + Copyright (c) 2006 - 2012 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..6ba8784cf3
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
> @@ -0,0 +1,507 @@
> +/** @file
> + File System Access for NvVarsFileLib
> +
> + Copyright (c) 2004 - 2014 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..f60fbc6112
> --- /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) 2009 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/SerializeVariablesLib/SerializeVa
> riablesLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.c
> new file mode 100644
> index 0000000000..c32a978550
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.c
> @@ -0,0 +1,869 @@
> +/** @file
> + Serialize Variables Library implementation
> +
> + Copyright (c) 2004 - 2011 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/PlatformDxe/Platform.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
> new file mode 100644
> index 0000000000..7bede1496d
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
> @@ -0,0 +1,865 @@
> +/** @file
> + This driver effectuates OVMF's 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/SimicsX58PlatformConfig.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 PlatformDxeStrings[];
> +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,
> &gSimicsX58PlatformConfigGuid,
> + 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
> + PlatformDxeStrings, // 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/PlatformDxe/PlatformConfig.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
> new file mode 100644
> index 0000000000..b3b2b34064
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
> @@ -0,0 +1,123 @@
> +/** @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
> +**/
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Guid/SimicsX58PlatformConfig.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, &gSimicsX58PlatformConfigGuid,
> + 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, &gSimicsX58PlatformConfigGuid,
> &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/PlatformPei/Cmos.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
> new file mode 100644
> index 0000000000..fa2c22116c
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
> @@ -0,0 +1,57 @@
> +/** @file
> + PC/AT CMOS access routines
> +
> + Copyright (c) 2006 - 2009 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/PlatformPei/FeatureControl.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
> new file mode 100644
> index 0000000000..692405e417
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/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/PlatformPei/Fv.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
> new file mode 100644
> index 0000000000..818d135c95
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
> @@ -0,0 +1,100 @@
> +/** @file
> + Build FV related hobs for platform.
> +
> + Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "PiPei.h"
> +#include "Platform.h"
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>
> +
> +
> +/**
> + 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/PlatformPei/MemDetect.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
> new file mode 100644
> index 0000000000..4c527baef2
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
> @@ -0,0 +1,568 @@
> +/** @file
> + Memory Detection for Virtual Machines.
> +
> + Copyright (c) 2006 - 2016 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/PlatformPei/Platform.c
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
> new file mode 100644
> index 0000000000..e64bdc7c56
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
> @@ -0,0 +1,631 @@
> +/** @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 ();
> + }
> + PeiFvInitialization ();
> + MemMapInitialization ();
> + }
> +
> + MiscInitialization ();
> + InstallFeatureControlCallback ();
> +
> + return EFI_SUCCESS;
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.c
> new file mode 100644
> index 0000000000..01a9ed40d5
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.c
> @@ -0,0 +1,108 @@
> +/** @file
> + Copyright (c) 2018 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/Sil
> iconPolicyUpdateLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.c
> new file mode 100644
> index 0000000000..6d9da67975
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.c
> @@ -0,0 +1,70 @@
> +/** @file
> + Copyright (c) 2018 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/SmbiosPlatformDxe/SmbiosPlatformDxe
> .c
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .c
> new file mode 100644
> index 0000000000..82a2d60959
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .c
> @@ -0,0 +1,148 @@
> +/** @file
> + This driver installs SMBIOS information for OVMF
> +
> + 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 OVMF
> +
> + @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..839626eb86
> --- /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 - 2018 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..76a8fbc081
> --- /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) 2008 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF ", 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..6395ec11e2
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
> @@ -0,0 +1,75 @@
> +/** @file
> + Platform specific defines for constructing ACPI tables
> +
> + Copyright (c) 2013 - 2008 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef _Platform_h_INCLUDED_
> +#define _Platform_h_INCLUDED_
> +
> +#include <PiDxe.h>
> +#include <IndustryStandard/Acpi.h>
> +
> +//
> +// ACPI table information used to initialize tables.
> +//
> +#define EFI_ACPI_OEM_ID 'O','V','M','F',' ',' ' // OEMID 6 bytes long
> +#define EFI_ACPI_OEM_TABLE_ID
> SIGNATURE_64('O','V','M','F','E','D','K','2') // OEM table id 8 bytes long
> +#define EFI_ACPI_OEM_REVISION 0x02000820
> +#define EFI_ACPI_CREATOR_ID SIGNATURE_32('O','V','M','F')
> +#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/SimicsX58PlatformConfig.
> h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.
> h
> new file mode 100644
> index 0000000000..f65f61d74d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.
> h
> @@ -0,0 +1,17 @@
> +/** @file
> + GUID for UEFI variables that are specific to OVMF configuration.
> +
> + Copyright (C) 2014, Red Hat, Inc.
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __SIMICSX58_PLATFORM_CONFIG_H__
> +#define __SIMICSX58_PLATFORM_CONFIG_H__
> +
> +#define SIMICSX58_PLATFORM_CONFIG_GUID \
> +{0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59,
> 0xa5}}
> +
> +extern EFI_GUID gSimicsX58PlatformConfigGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> new file mode 100644
> index 0000000000..36c08176d1
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> @@ -0,0 +1,106 @@
> +/** @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>
> +
> +//
> +// 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/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> new file mode 100644
> index 0000000000..12aeb1227c
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> @@ -0,0 +1,298 @@
> +/** @file
> + EFI ISA ACPI Protocol is used to enumerate and manage all the ISA controllers
> on
> + the platform's ISA Bus.
> +
> +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef __ISA_ACPI_H_
> +#define __ISA_ACPI_H_
> +
> +///
> +/// Global ID for the EFI ISA ACPI Protocol.
> +///
> +#define EFI_ISA_ACPI_PROTOCOL_GUID \
> + { \
> + 0x64a892dc, 0x5561, 0x4536, { 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33,
> 0x55 } \
> + }
> +
> +///
> +/// Forward declaration fo the EFI ISA ACPI Protocol
> +///
> +typedef struct _EFI_ISA_ACPI_PROTOCOL EFI_ISA_ACPI_PROTOCOL;
> +
> +///
> +/// ISA ACPI Protocol interrupt resource attributes.
> +///
> +#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_EDGE_SENSITIVE 0x01 ///<
> Edge triggered interrupt on a rising edge.
> +#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_EDGE_SENSITIVE 0x02 ///<
> Edge triggered interrupt on a falling edge.
> +#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_LEVEL_SENSITIVE 0x04 ///<
> Level sensitive interrupt active high.
> +#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_LEVEL_SENSITIVE 0x08 ///<
> Level sensitive interrupt active low.
> +
> +///
> +/// ISA ACPI Protocol DMA resource attributes.
> +///
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_MASK 0x03 ///< Bit mask
> of supported DMA speed attributes.
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_COMPATIBILITY 0x00 ///< ISA
> controller supports compatibility mode DMA transfers.
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_A 0x01 ///< ISA
> controller supports type A DMA transfers.
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_B 0x02 ///< ISA
> controller supports type B DMA transfers.
> +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_F 0x03 ///< ISA
> controller supports type F DMA transfers.
> +#define EFI_ISA_ACPI_DMA_COUNT_BY_BYTE 0x04 ///< ISA
> controller increments DMA address by bytes (8-bit).
> +#define EFI_ISA_ACPI_DMA_COUNT_BY_WORD 0x08 ///< ISA
> controller increments DMA address by words (16-bit).
> +#define EFI_ISA_ACPI_DMA_BUS_MASTER 0x10 ///< ISA
> controller is a DMA bus master.
> +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT 0x20 ///< ISA
> controller only supports 8-bit DMA transfers.
> +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT_AND_16_BIT 0x40
> ///< ISA controller both 8-bit and 16-bit DMA transfers.
> +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_16_BIT 0x80 ///< ISA
> controller only supports 16-bit DMA transfers.
> +
> +///
> +/// ISA ACPI Protocol MMIO resource attributes
> +///
> +#define EFI_ISA_ACPI_MEMORY_WIDTH_MASK 0x03 ///< Bit mask
> of supported ISA memory width attributes.
> +#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT 0x00 ///< ISA
> MMIO region only supports 8-bit access.
> +#define EFI_ISA_ACPI_MEMORY_WIDTH_16_BIT 0x01 ///< ISA
> MMIO region only supports 16-bit access.
> +#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT_AND_16_BIT 0x02 ///<
> ISA MMIO region supports both 8-bit and 16-bit access.
> +#define EFI_ISA_ACPI_MEMORY_WRITEABLE 0x04 ///< ISA MMIO
> region supports write transactions.
> +#define EFI_ISA_ACPI_MEMORY_CACHEABLE 0x08 ///< ISA MMIO
> region supports being cached.
> +#define EFI_ISA_ACPI_MEMORY_SHADOWABLE 0x10 ///< ISA
> MMIO region may be shadowed.
> +#define EFI_ISA_ACPI_MEMORY_EXPANSION_ROM 0x20 ///< ISA
> MMIO region is an expansion ROM.
> +
> +///
> +/// ISA ACPI Protocol I/O resource attributes
> +///
> +#define EFI_ISA_ACPI_IO_DECODE_10_BITS 0x01 ///< ISA
> controllers uses a 10-bit address decoder for I/O cycles.
> +#define EFI_ISA_ACPI_IO_DECODE_16_BITS 0x02 ///< ISA
> controllers uses a 16-bit address decoder for I/O cycles.
> +
> +///
> +/// EFI ISA ACPI resource type
> +///
> +typedef enum {
> + EfiIsaAcpiResourceEndOfList, ///< Marks the end if a resource list.
> + EfiIsaAcpiResourceIo, ///< ISA I/O port resource range.
> + EfiIsaAcpiResourceMemory, ///< ISA MMIO resource range.
> + EfiIsaAcpiResourceDma, ///< ISA DMA resource.
> + EfiIsaAcpiResourceInterrupt ///< ISA interrupt resource.
> +} EFI_ISA_ACPI_RESOURCE_TYPE;
> +
> +///
> +/// EFI ISA ACPI generic resource structure
> +///
> +typedef struct {
> + EFI_ISA_ACPI_RESOURCE_TYPE Type; ///< The type of resource (I/O,
> MMIO, DMA, Interrupt).
> + UINT32 Attribute; ///< Bit mask of attributes associated with this
> resource. See EFI_ISA_ACPI_xxx macros for valid combinations.
> + UINT32 StartRange; ///< The start of the resource range.
> + UINT32 EndRange; ///< The end of the resource range.
> +} EFI_ISA_ACPI_RESOURCE;
> +
> +///
> +/// EFI ISA ACPI resource device identifier
> +///
> +typedef struct {
> + UINT32 HID; ///< The ACPI Hardware Identifier value associated with an ISA
> controller. Matchs ACPI DSDT contents.
> + UINT32 UID; ///< The ACPI Unique Identifier value associated with an ISA
> controller. Matches ACPI DSDT contents.
> +} EFI_ISA_ACPI_DEVICE_ID;
> +
> +///
> +/// EFI ISA ACPI resource list
> +///
> +typedef struct {
> + EFI_ISA_ACPI_DEVICE_ID Device; ///< The ACPI HID/UID associated with
> an ISA controller.
> + EFI_ISA_ACPI_RESOURCE *ResourceItem; ///< A pointer to the list of
> resources associated with an ISA controller.
> +} EFI_ISA_ACPI_RESOURCE_LIST;
> +
> +/**
> + Enumerates the ISA controllers on an ISA bus.
> +
> + This service allows all the ISA controllers on an ISA bus to be enumerated. If
> + Device is a pointer to a NULL value, then the first ISA controller on the ISA
> + bus is returned in Device and EFI_SUCCESS is returned. If Device is a pointer
> + to a value that was returned on a prior call to DeviceEnumerate(), then the
> next
> + ISA controller on the ISA bus is returned in Device and EFI_SUCCESS is
> returned.
> + If Device is a pointer to the last ISA controller on the ISA bus, then
> + EFI_NOT_FOUND is returned.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[out] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> +
> + @retval EFI_SUCCESS The next ISA controller on the ISA bus was returned.
> + @retval EFI_NOT_FOUND No device found.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_DEVICE_ENUMERATE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + OUT EFI_ISA_ACPI_DEVICE_ID **Device
> + );
> +
> +/**
> + Sets the power state of an ISA controller.
> +
> + This services sets the power state of the ISA controller specified by Device to
> + the power state specified by OnOff. TRUE denotes on, FALSE denotes off.
> + If the power state is sucessfully set on the ISA Controller, then
> + EFI_SUCCESS is returned.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
> + @param[in] OnOff TRUE denotes on, FALSE denotes off.
> +
> + @retval EFI_SUCCESS Successfully set the power state of the ISA controller.
> + @retval Other The ISA controller could not be placed in the requested
> power state.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_SET_DEVICE_POWER)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + IN BOOLEAN OnOff
> + );
> +
> +/**
> + Retrieves the current set of resources associated with an ISA controller.
> +
> + Retrieves the set of I/O, MMIO, DMA, and interrupt resources currently
> + assigned to the ISA controller specified by Device. These resources
> + are returned in ResourceList.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> + @param[out] ResourceList The pointer to the current resource list for Device.
> +
> + @retval EFI_SUCCESS Successfully retrieved the current resource list.
> + @retval EFI_NOT_FOUND The resource list could not be retrieved.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_GET_CUR_RESOURCE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
> + );
> +
> +/**
> + Retrieves the set of possible resources that may be assigned to an ISA
> controller
> + with SetResource().
> +
> + Retrieves the possible sets of I/O, MMIO, DMA, and interrupt resources for
> the
> + ISA controller specified by Device. The sets are returned in ResourceList.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> + @param[out] ResourceList The pointer to the returned list of resource lists.
> +
> + @retval EFI_UNSUPPORTED This service is not supported.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_GET_POS_RESOURCE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
> + );
> +
> +/**
> + Assigns resources to an ISA controller.
> +
> + Assigns the I/O, MMIO, DMA, and interrupt resources specified by
> ResourceList
> + to the ISA controller specified by Device. ResourceList must match a resource
> list returned by GetPosResource() for the same ISA controller.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> + @param[in] ResourceList The pointer to a resources list that must be one of
> the
> + resource lists returned by GetPosResource() for the
> + ISA controller specified by Device.
> +
> + @retval EFI_SUCCESS Successfully set resources on the ISA controller.
> + @retval Other The resources could not be set for the ISA controller.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_SET_RESOURCE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + IN EFI_ISA_ACPI_RESOURCE_LIST *ResourceList
> + );
> +
> +/**
> + Enables or disables an ISA controller.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to the ISA controller to enable/disable.
> + @param[in] Enable TRUE to enable the ISA controller. FALSE to disable the
> + ISA controller.
> +
> + @retval EFI_SUCCESS Successfully enabled/disabled the ISA controller.
> + @retval Other The ISA controller could not be placed in the requested
> state.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_ENABLE_DEVICE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> + IN BOOLEAN Enable
> + );
> +
> +/**
> + Initializes an ISA controller, so that it can be used. This service must be called
> + before SetResource(), EnableDevice(), or SetPower() will behave as expected.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> + @param[in] Device The pointer to an ISA controller named by ACPI HID/UID.
> +
> + @retval EFI_SUCCESS Successfully initialized an ISA controller.
> + @retval Other The ISA controller could not be initialized.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_INIT_DEVICE)(
> + IN EFI_ISA_ACPI_PROTOCOL *This,
> + IN EFI_ISA_ACPI_DEVICE_ID *Device
> + );
> +
> +/**
> + Initializes all the HW states required for the ISA controllers on the ISA bus
> + to be enumerated and managed by the rest of the services in this prorotol.
> + This service must be called before any of the other services in this
> + protocol will function as expected.
> +
> + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> +
> + @retval EFI_SUCCESS Successfully initialized all required hardware states.
> + @retval Other The ISA interface could not be initialized.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_ACPI_INTERFACE_INIT)(
> + IN EFI_ISA_ACPI_PROTOCOL *This
> + );
> +
> +///
> +/// The EFI_ISA_ACPI_PROTOCOL provides the services to enumerate and
> manage
> +/// ISA controllers on an ISA bus. These services include the ability to initialize,
> +/// enable, disable, and manage the power state of ISA controllers. It also
> +/// includes services to query current resources, query possible resources,
> +/// and assign resources to an ISA controller.
> +///
> +struct _EFI_ISA_ACPI_PROTOCOL {
> + EFI_ISA_ACPI_DEVICE_ENUMERATE DeviceEnumerate;
> + EFI_ISA_ACPI_SET_DEVICE_POWER SetPower;
> + EFI_ISA_ACPI_GET_CUR_RESOURCE GetCurResource;
> + EFI_ISA_ACPI_GET_POS_RESOURCE GetPosResource;
> + EFI_ISA_ACPI_SET_RESOURCE SetResource;
> + EFI_ISA_ACPI_ENABLE_DEVICE EnableDevice;
> + EFI_ISA_ACPI_INIT_DEVICE InitDevice;
> + EFI_ISA_ACPI_INTERFACE_INIT InterfaceInit;
> +};
> +
> +extern EFI_GUID gEfiIsaAcpiProtocolGuid;
> +
> +#endif
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> new file mode 100644
> index 0000000000..30000305fb
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> @@ -0,0 +1,356 @@
> +/** @file
> + ISA I/O Protocol is used by ISA device drivers to perform I/O, MMIO and DMA
> + operations on the ISA controllers they manage.
> +
> +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _EFI_ISA_IO_H_
> +#define _EFI_ISA_IO_H_
> +
> +#include <Protocol/IsaAcpi.h>
> +
> +///
> +/// Global ID for the EFI_ISA_IO_PROTOCOL
> +///
> +#define EFI_ISA_IO_PROTOCOL_GUID \
> + { \
> + 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1,
> 0x4d } \
> + }
> +
> +///
> +/// Forward declaration for the EFI_ISA_IO_PROTOCOL.
> +///
> +typedef struct _EFI_ISA_IO_PROTOCOL EFI_ISA_IO_PROTOCOL;
> +
> +///
> +/// Width of EFI_ISA_IO_PROTOCOL I/O Port and MMIO operations.
> +///
> +typedef enum {
> + EfiIsaIoWidthUint8 = 0, ///< 8-bit operation.
> + EfiIsaIoWidthUint16, ///< 16-bit operation.
> + EfiIsaIoWidthUint32, ///< 32-bit operation
> + EfiIsaIoWidthReserved,
> + EfiIsaIoWidthFifoUint8, ///< 8-bit FIFO operation.
> + EfiIsaIoWidthFifoUint16, ///< 16-bit FIFO operation.
> + EfiIsaIoWidthFifoUint32, ///< 32-bit FIFO operation.
> + EfiIsaIoWidthFifoReserved,
> + EfiIsaIoWidthFillUint8, ///< 8-bit Fill operation.
> + EfiIsaIoWidthFillUint16, ///< 16-bit Fill operation.
> + EfiIsaIoWidthFillUint32, ///< 32-bit Fill operation.
> + EfiIsaIoWidthFillReserved,
> + EfiIsaIoWidthMaximum
> +} EFI_ISA_IO_PROTOCOL_WIDTH;
> +
> +///
> +/// Attributes for the EFI_ISA_IO_PROTOCOL common DMA buffer allocations.
> +///
> +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x080 ///<
> Map a memory range so write are combined.
> +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_CACHED 0x800 ///< Map a
> memory range so all read and write accesses are cached.
> +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000 ///< Disable
> a memory range.
> +
> +///
> +/// Channel attribute for EFI_ISA_IO_PROTOCOL slave DMA requests
> +///
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE 0x001
> ///< Set the speed of the DMA transfer in compatible mode.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_A 0x002 ///< Not
> supported.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_B 0x004 ///< Not
> supported.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_C 0x008 ///< Not
> supported.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8 0x010 ///<
> Request 8-bit DMA transfers. Only available on channels 0..3.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16 0x020 ///<
> Request 16-bit DMA transfers. Only available on channels 4..7.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE 0x040 ///<
> Request a single DMA transfer.
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE 0x080
> ///< Request multiple DMA transfers until TC (Terminal Count) or EOP (End of
> Process).
> +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_AUTO_INITIALIZE 0x100 ///<
> Automatically reload base and count at the end of the DMA transfer.
> +
> +///
> +/// The DMA opreration type for EFI_ISA_IO_PROTOCOL DMA requests.
> +///
> +typedef enum {
> + ///
> + /// A read operation from system memory by a bus master.
> + ///
> + EfiIsaIoOperationBusMasterRead,
> + ///
> + /// A write operation to system memory by a bus master.
> + ///
> + EfiIsaIoOperationBusMasterWrite,
> + ///
> + /// Provides both read and write access to system memory by both the
> processor
> + /// and a bus master. The buffer is coherent from both the processor's and
> the
> + /// bus master's point of view.
> + ///
> + EfiIsaIoOperationBusMasterCommonBuffer,
> + ///
> + /// A read operation from system memory by a slave device.
> + ///
> + EfiIsaIoOperationSlaveRead,
> + ///
> + /// A write operation to system memory by a slave master.
> + ///
> + EfiIsaIoOperationSlaveWrite,
> + EfiIsaIoOperationMaximum
> +} EFI_ISA_IO_PROTOCOL_OPERATION;
> +
> +/**
> + Performs ISA I/O and MMIO Read/Write Cycles
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Width Specifies the width of the I/O or MMIO operation.
> + @param[in] Offset The offset into the ISA I/O or MMIO space to start the
> + operation.
> + @param[in] Count The number of I/O or MMIO operations to perform.
> + @param[in, out] Buffer For read operations, the destination buffer to store
> + the results. For write operations, the source buffer to
> + write data from.
> +
> + @retval EFI_SUCCESS The data was successfully read from or written to
> the device.
> + @retval EFI_UNSUPPORTED The Offset is not valid for this device.
> + @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
> + @retval EFI_OUT_OF_RESOURCES The request could not be completed due
> to a lack of resources.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_IO_MEM)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
> + IN UINT32 Offset,
> + IN UINTN Count,
> + IN OUT VOID *Buffer
> + );
> +
> +///
> +/// Structure of functions for accessing ISA I/O and MMIO space.
> +///
> +typedef struct {
> + ///
> + /// Read from ISA I/O or MMIO space.
> + ///
> + EFI_ISA_IO_PROTOCOL_IO_MEM Read;
> + ///
> + /// Write to ISA I/O or MMIO space.
> + ///
> + EFI_ISA_IO_PROTOCOL_IO_MEM Write;
> +} EFI_ISA_IO_PROTOCOL_ACCESS;
> +
> +/**
> + Copies data from one region of ISA MMIO space to another region of ISA
> + MMIO space.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Width Specifies the width of the MMIO copy operation.
> + @param[in] DestOffset The offset of the destination in ISA MMIO space.
> + @param[in] SrcOffset The offset of the source in ISA MMIO space.
> + @param[in] Count The number tranfers to perform for this copy
> operation.
> +
> + @retval EFI_SUCCESS The data was copied sucessfully.
> + @retval EFI_UNSUPPORTED The DestOffset or SrcOffset is not valid for
> this device.
> + @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
> + @retval EFI_OUT_OF_RESOURCES The request could not be completed due
> to a lack of resources.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_COPY_MEM)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
> + IN UINT32 DestOffset,
> + IN UINT32 SrcOffset,
> + IN UINTN Count
> + );
> +
> +/**
> + Maps a memory region for DMA.
> +
> + This function returns the device-specific addresses required to access system
> memory.
> + This function is used to map system memory for ISA DMA operations. All ISA
> DMA
> + operations must be performed through their mapped addresses, and such
> mappings must
> + be freed with EFI_ISA_IO_PROTOCOL.Unmap() after the DMA operation is
> completed.
> +
> + If the DMA operation is a single read or write data transfer through an ISA bus
> + master, then EfiIsaIoOperationBusMasterRead or
> EfiIsaIoOperationBusMasterWrite
> + is used and the range is unmapped to complete the operation. If the DMA
> operation
> + is a single read or write data transfer through an ISA slave controller, then
> + EfiIsaIoOperationSlaveRead or EfiIsaIoOperationSlaveWrite is used and the
> range
> + is unmapped to complete the operation.
> +
> + If performing a DMA read operation, all the data must be present in system
> memory before the Map() is performed. Similarly,
> + if performing a DMA write operation, the data must not be accessed in system
> + memory until EFI_ISA_IO_PROTOCOL.Unmap() is performed. Bus master
> operations that
> + require both read and write access or require multiple host device
> interactions
> + within the same mapped region must use
> EfiIsaIoOperationBusMasterCommonBuffer.
> + However, only memory allocated via the
> EFI_ISA_IO_PROTOCOL.AllocateBuffer() interface
> + is guaranteed to be able to be mapped for this operation type. In all mapping
> + requests the NumberOfBytes returned may be less than originally requested.
> It is
> + the caller's responsibility to make additional requests to complete the entire
> + transfer.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Operation Indicates the type of DMA (slave or bus
> master),
> + and if the DMA operation is going to read or
> + write to system memory.
> + @param[in] ChannelNumber The slave channel number to use for this
> DMA
> + operation. If Operation and ChannelAttributes
> + shows that this device performs bus mastering
> + DMA, then this field is ignored. The legal
> + range for this field is 0..7.
> + @param[in] ChannelAttributes A bitmask of the attributes used to
> configure
> + the slave DMA channel for this DMA operation.
> + See EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_* for the
> + legal bit combinations.
> + @param[in] HostAddress The system memory address to map to the
> device.
> + @param[in, out] NumberOfBytes On input the number of bytes to map.
> On
> + output the number of bytes that were mapped.
> + @param[out] DeviceAddress The resulting map address for the bus
> master
> + device to use to access the hosts HostAddress.
> + @param[out] Mapping A returned value that must be passed to into
> + EFI_ISA_IO_PROTOCOL.Unmap() to free all the the
> + resources associated with this map request.
> +
> + @retval EFI_SUCCESS The range was mapped for the returned
> NumberOfBytes.
> + @retval EFI_INVALID_PARAMETER The Operation is undefined.
> + @retval EFI_INVALID_PARAMETER The HostAddress is undefined.
> + @retval EFI_UNSUPPORTED The HostAddress can not be mapped as a
> common buffer.
> + @retval EFI_DEVICE_ERROR The system hardware could not map the
> requested address.
> + @retval EFI_OUT_OF_RESOURCES The memory pages could not be
> allocated.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_MAP)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN EFI_ISA_IO_PROTOCOL_OPERATION Operation,
> + IN UINT8 ChannelNumber OPTIONAL,
> + IN UINT32 ChannelAttributes,
> + IN VOID *HostAddress,
> + IN OUT UINTN *NumberOfBytes,
> + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
> + OUT VOID **Mapping
> + );
> +
> +/**
> + Unmaps a memory region that was previously mapped with
> EFI_ISA_IO_PROTOCOL.Map().
> +
> + The EFI_ISA_IO_PROTOCOL.Map() operation is completed and any
> corresponding
> + resources are released. If the operation was EfiIsaIoOperationSlaveWrite
> + or EfiIsaIoOperationBusMasterWrite, the data is committed to system
> memory.
> + Any resources used for the mapping are freed.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Mapping The mapping value returned from
> EFI_ISA_IO_PROTOCOL.Map().
> +
> + @retval EFI_SUCCESS The memory region was unmapped.
> + @retval EFI_DEVICE_ERROR The data was not committed to the target
> system memory.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_UNMAP)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN VOID *Mapping
> + );
> +
> +/**
> + Allocates pages that are suitable for an
> EfiIsaIoOperationBusMasterCommonBuffer
> + mapping.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Type The type allocation to perform.
> + @param[in] MemoryType The type of memory to allocate.
> + @param[in] Pages The number of pages to allocate.
> + @param[out] HostAddress A pointer to store the base address of the
> allocated range.
> + @param[in] Attributes The requested bit mask of attributes for the
> allocated range.
> +
> + @retval EFI_SUCCESS The requested memory pages were allocated.
> + @retval EFI_INVALID_PARAMETER Type is invalid.
> + @retval EFI_INVALID_PARAMETER MemoryType is invalid.
> + @retval EFI_INVALID_PARAMETER HostAddress is NULL.
> + @retval EFI_UNSUPPORTED Attributes is unsupported.
> + @retval EFI_UNSUPPORTED The memory range specified by
> HostAddress, Pages,
> + and Type is not available for common buffer use.
> + @retval EFI_OUT_OF_RESOURCES The memory pages could not be
> allocated.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN EFI_ALLOCATE_TYPE Type,
> + IN EFI_MEMORY_TYPE MemoryType,
> + IN UINTN Pages,
> + OUT VOID **HostAddress,
> + IN UINT64 Attributes
> + );
> +
> +/**
> + Frees a common buffer that was allocated with
> EFI_ISA_IO_PROTOCOL.AllocateBuffer().
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> + @param[in] Pages The number of pages to free from the previously
> allocated common buffer.
> + @param[in] HostAddress The base address of the previously allocated
> common buffer.
> +
> +
> + @retval EFI_SUCCESS The requested memory pages were freed.
> + @retval EFI_INVALID_PARAMETER The memory was not allocated with
> EFI_ISA_IO.AllocateBufer().
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_FREE_BUFFER)(
> + IN EFI_ISA_IO_PROTOCOL *This,
> + IN UINTN Pages,
> + IN VOID *HostAddress
> + );
> +
> +/**
> + Flushes a DMA buffer, which forces all DMA posted write transactions to
> complete.
> +
> + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> +
> + @retval EFI_SUCCESS The DMA buffers were flushed.
> + @retval EFI_DEVICE_ERROR The buffers were not flushed due to a
> hardware error.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_ISA_IO_PROTOCOL_FLUSH)(
> + IN EFI_ISA_IO_PROTOCOL *This
> + );
> +
> +///
> +/// The EFI_ISA_IO_PROTOCOL provides the basic Memory, I/O, and DMA
> interfaces
> +/// used to abstract accesses to ISA controllers. There is one
> EFI_ISA_IO_PROTOCOL
> +/// instance for each ISA controller on a ISA bus. A device driver that wishes
> +/// to manage an ISA controller in a system will have to retrieve the
> +/// ISA_PCI_IO_PROTOCOL instance associated with the ISA controller.
> +///
> +struct _EFI_ISA_IO_PROTOCOL {
> + EFI_ISA_IO_PROTOCOL_ACCESS Mem;
> + EFI_ISA_IO_PROTOCOL_ACCESS Io;
> + EFI_ISA_IO_PROTOCOL_COPY_MEM CopyMem;
> + EFI_ISA_IO_PROTOCOL_MAP Map;
> + EFI_ISA_IO_PROTOCOL_UNMAP Unmap;
> + EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer;
> + EFI_ISA_IO_PROTOCOL_FREE_BUFFER FreeBuffer;
> + EFI_ISA_IO_PROTOCOL_FLUSH Flush;
> + ///
> + /// The list of I/O , MMIO, DMA, and Interrupt resources associated with the
> + /// ISA controller abstracted by this instance of the EFI_ISA_IO_PROTOCOL.
> + ///
> + EFI_ISA_ACPI_RESOURCE_LIST *ResourceList;
> + ///
> + /// The size, in bytes, of the ROM image.
> + ///
> + UINT32 RomSize;
> + ///
> + /// A pointer to the in memory copy of the ROM image. The ISA Bus Driver is
> responsible
> + /// for allocating memory for the ROM image, and copying the contents of the
> ROM to memory
> + /// during ISA Bus initialization.
> + ///
> + VOID *RomImage;
> +};
> +
> +extern EFI_GUID gEfiIsaIoProtocolGuid;
> +
> +#endif
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> new file mode 100644
> index 0000000000..c38f2feba7
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> @@ -0,0 +1,291 @@
> +/** @file
> + This protocol abstracts the 8259 interrupt controller. This includes
> + PCI IRQ routing needed to program the PCI Interrupt Line register.
> +
> + Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Revision Reference:
> + This protocol is defined in Framework for EFI Compatibility Support Module
> spec
> + Version 0.97.
> +
> +**/
> +
> +#ifndef _EFI_LEGACY_8259_H_
> +#define _EFI_LEGACY_8259_H_
> +
> +
> +#define EFI_LEGACY_8259_PROTOCOL_GUID \
> + { \
> + 0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed,
> 0xc1 } \
> + }
> +
> +typedef struct _EFI_LEGACY_8259_PROTOCOL
> EFI_LEGACY_8259_PROTOCOL;
> +
> +typedef enum {
> + Efi8259Irq0,
> + Efi8259Irq1,
> + Efi8259Irq2,
> + Efi8259Irq3,
> + Efi8259Irq4,
> + Efi8259Irq5,
> + Efi8259Irq6,
> + Efi8259Irq7,
> + Efi8259Irq8,
> + Efi8259Irq9,
> + Efi8259Irq10,
> + Efi8259Irq11,
> + Efi8259Irq12,
> + Efi8259Irq13,
> + Efi8259Irq14,
> + Efi8259Irq15,
> + Efi8259IrqMax
> +} EFI_8259_IRQ;
> +
> +typedef enum {
> + Efi8259LegacyMode,
> + Efi8259ProtectedMode,
> + Efi8259MaxMode
> +} EFI_8259_MODE;
> +
> +/**
> + Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
> + the legacy mode mask and the protected mode mask. The base address for
> the 8259
> + is different for legacy and protected mode, so two masks are required.
> +
> + @param This The protocol instance pointer.
> + @param MasterBase The base vector for the Master PIC in the 8259
> controller.
> + @param SlaveBase The base vector for the Slave PIC in the 8259
> controller.
> +
> + @retval EFI_SUCCESS The new bases were programmed.
> + @retval EFI_DEVICE_ERROR A device error occured programming the
> vector bases.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_SET_VECTOR_BASE)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT8 MasterBase,
> + IN UINT8 SlaveBase
> + );
> +
> +/**
> + Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
> + the legacy mode mask and the protected mode mask. The base address for
> the 8259
> + is different for legacy and protected mode, so two masks are required.
> +
> + @param This The protocol instance pointer.
> + @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> +
> + @retval EFI_SUCCESS 8259 status returned.
> + @retval EFI_DEVICE_ERROR Error reading 8259.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_GET_MASK)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + OUT UINT16 *LegacyMask, OPTIONAL
> + OUT UINT16 *LegacyEdgeLevel, OPTIONAL
> + OUT UINT16 *ProtectedMask, OPTIONAL
> + OUT UINT16 *ProtectedEdgeLevel OPTIONAL
> + );
> +
> +/**
> + Set the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
> + the legacy mode mask and the protected mode mask. The base address for
> the 8259
> + is different for legacy and protected mode, so two masks are required.
> + Also set the edge/level masks.
> +
> + @param This The protocol instance pointer.
> + @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15.
> + @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> +
> + @retval EFI_SUCCESS 8259 status returned.
> + @retval EFI_DEVICE_ERROR Error writing 8259.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_SET_MASK)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT16 *LegacyMask, OPTIONAL
> + IN UINT16 *LegacyEdgeLevel, OPTIONAL
> + IN UINT16 *ProtectedMask, OPTIONAL
> + IN UINT16 *ProtectedEdgeLevel OPTIONAL
> + );
> +
> +/**
> + Set the 8259 mode of operation. The base address for the 8259 is different
> for
> + legacy and protected mode. The legacy mode requires the master 8259 to
> have a
> + master base of 0x08 and the slave base of 0x70. The protected mode base
> locations
> + are not defined. Interrupts must be masked by the caller before this function
> + is called. The interrupt mask from the current mode is saved. The interrupt
> + mask for the new mode is Mask, or if Mask does not exist the previously saved
> + mask is used.
> +
> + @param This The protocol instance pointer.
> + @param Mode The mode of operation. i.e. the real mode or
> protected mode.
> + @param Mask Optional interupt mask for the new mode.
> + @param EdgeLevel Optional trigger mask for the new mode.
> +
> + @retval EFI_SUCCESS 8259 programmed.
> + @retval EFI_DEVICE_ERROR Error writing to 8259.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_SET_MODE)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_MODE Mode,
> + IN UINT16 *Mask, OPTIONAL
> + IN UINT16 *EdgeLevel OPTIONAL
> + );
> +
> +/**
> + Convert from IRQ to processor interrupt vector number.
> +
> + @param This The protocol instance pointer.
> + @param Irq 8259 IRQ0 - IRQ15.
> + @param Vector The processor vector number that matches an Irq.
> +
> + @retval EFI_SUCCESS The Vector matching Irq is returned.
> + @retval EFI_INVALID_PARAMETER The Irq not valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_GET_VECTOR)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + OUT UINT8 *Vector
> + );
> +
> +/**
> + Enable Irq by unmasking interrupt in 8259
> +
> + @param This The protocol instance pointer.
> + @param Irq 8259 IRQ0 - IRQ15.
> + @param LevelTriggered TRUE if level triggered. FALSE if edge triggered.
> +
> + @retval EFI_SUCCESS The Irq was enabled on 8259.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_ENABLE_IRQ)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + IN BOOLEAN LevelTriggered
> + );
> +
> +/**
> + Disable Irq by masking interrupt in 8259
> +
> + @param This The protocol instance pointer.
> + @param Irq 8259 IRQ0 - IRQ15.
> +
> + @retval EFI_SUCCESS The Irq was disabled on 8259.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_DISABLE_IRQ)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + );
> +
> +/**
> + PciHandle represents a PCI config space of a PCI function. Vector
> + represents Interrupt Pin (from PCI config space) and it is the data
> + that is programmed into the Interrupt Line (from the PCI config space)
> + register.
> +
> + @param This The protocol instance pointer.
> + @param PciHandle The PCI function to return the vector for.
> + @param Vector The vector for the function it matches.
> +
> + @retval EFI_SUCCESS A valid Vector was returned.
> + @retval EFI_INVALID_PARAMETER PciHandle not valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_GET_INTERRUPT_LINE)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_HANDLE PciHandle,
> + OUT UINT8 *Vector
> + );
> +
> +/**
> + Send an EOI to 8259
> +
> + @param This The protocol instance pointer.
> + @param Irq 8259 IRQ0 - IRQ15.
> +
> + @retval EFI_SUCCESS EOI was successfully sent to 8259.
> + @retval EFI_INVALID_PARAMETER The Irq isnot valid.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_LEGACY_8259_END_OF_INTERRUPT)(
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + );
> +
> +/**
> + @par Protocol Description:
> + Abstracts the 8259 and APIC hardware control between EFI usage and
> + Compatibility16 usage.
> +
> + @param SetVectorBase
> + Sets the vector bases for master and slave PICs.
> +
> + @param GetMask
> + Gets IRQ and edge/level masks for 16-bit real mode and 32-bit protected
> mode.
> +
> + @param SetMask
> + Sets the IRQ and edge\level masks for 16-bit real mode and 32-bit protected
> mode.
> +
> + @param SetMode
> + Sets PIC mode to 16-bit real mode or 32-bit protected mode.
> +
> + @param GetVector
> + Gets the base vector assigned to an IRQ.
> +
> + @param EnableIrq
> + Enables an IRQ.
> +
> + @param DisableIrq
> + Disables an IRQ.
> +
> + @param GetInterruptLine
> + Gets an IRQ that is assigned to a PCI device.
> +
> + @param EndOfInterrupt
> + Issues the end of interrupt command.
> +
> +**/
> +struct _EFI_LEGACY_8259_PROTOCOL {
> + EFI_LEGACY_8259_SET_VECTOR_BASE SetVectorBase;
> + EFI_LEGACY_8259_GET_MASK GetMask;
> + EFI_LEGACY_8259_SET_MASK SetMask;
> + EFI_LEGACY_8259_SET_MODE SetMode;
> + EFI_LEGACY_8259_GET_VECTOR GetVector;
> + EFI_LEGACY_8259_ENABLE_IRQ EnableIrq;
> + EFI_LEGACY_8259_DISABLE_IRQ DisableIrq;
> + EFI_LEGACY_8259_GET_INTERRUPT_LINE GetInterruptLine;
> + EFI_LEGACY_8259_END_OF_INTERRUPT EndOfInterrupt;
> +};
> +
> +extern EFI_GUID gEfiLegacy8259ProtocolGuid;
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateM
> ap.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateM
> ap.h
> new file mode 100644
> index 0000000000..640ac4943d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateM
> ap.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/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> new file mode 100644
> index 0000000000..c79111d811
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> @@ -0,0 +1,54 @@
> +/** @file
> + OVMF Platform definitions
> +
> + Copyright (C) 2015, Red Hat, Inc.
> + Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#ifndef __OVMF_PLATFORMS_H__
> +#define __OVMF_PLATFORMS_H__
> +
> +#include <Library/PciLib.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <IndustryStandard/X58Ich10.h>
> +#include <IndustryStandard/I440FxPiix4.h> // TODO: remove
> +
> +//
> +// 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/LoadLinuxLib/Ia32/JumpToKern
> el.nasm
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKern
> el.nasm
> new file mode 100644
> index 0000000000..3f3cd33c8a
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKern
> el.nasm
> @@ -0,0 +1,41 @@
> +; @file
> +; Copyright (c) 2006 - 2013 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..c4cc4dd8e7
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
> @@ -0,0 +1,52 @@
> +/** @file
> + Boot UEFI Linux.
> +
> + Copyright (c) 2008 - 2013 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/LoadLinuxLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> new file mode 100644
> index 0000000000..89664f4e42
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> @@ -0,0 +1,42 @@
> +## @file
> +#
> +# Copyright (c) 2008 - 2012 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = LoadLinuxLib
> + FILE_GUID = 63CC8497-C9D0-46A8-AC08-49DF92A2FF62
> + MODULE_TYPE = BASE
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = LoadLinuxLib
> +
> +#
> +# 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
> + OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + MemoryAllocationLib
> + BaseMemoryLib
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKerne
> l.nasm
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKerne
> l.nasm
> new file mode 100644
> index 0000000000..79e6b8e7ba
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKerne
> l.nasm
> @@ -0,0 +1,85 @@
> +; @file
> +; Copyright (c) 2006 - 2013 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..92aa038cdd
> --- /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 - 2011 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..e4c3b7ccff
> --- /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 - 2018 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/SerializeVariablesLib/SerializeVa
> riablesLib.h
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.h
> new file mode 100644
> index 0000000000..7e78cd4b21
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.h
> @@ -0,0 +1,33 @@
> +/** @file
> + Serialize Variables Library implementation
> +
> + Copyright (c) 2009 - 2011 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/SerializeVa
> riablesLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.inf
> new file mode 100644
> index 0000000000..25901192b2
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> riablesLib.inf
> @@ -0,0 +1,36 @@
> +## @file
> +# Serialize Variables Library implementation
> +#
> +# This library serializes and deserializes UEFI variables
> +#
> +# Copyright (c) 2006 - 2018 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
> + OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + DebugLib
> + MemoryAllocationLib
> + UefiBootServicesTableLib
> + UefiRuntimeServicesTableLib
> +
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> new file mode 100644
> index 0000000000..63b5e52575
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> @@ -0,0 +1,37 @@
> +/** @file
> + This driver effectuates OVMF's 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/PlatformDxe/Platform.inf
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
> new file mode 100644
> index 0000000000..804ab59610
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.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 = PlatformDxe
> + 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/SimicsOpenBoardPkg.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
> + gSimicsX58PlatformConfigGuid
> +
> +[Depex]
> + gEfiHiiConfigRoutingProtocolGuid AND
> + gEfiHiiDatabaseProtocolGuid AND
> + gEfiVariableArchProtocolGuid AND
> + gEfiVariableWriteArchProtocolGuid
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
> new file mode 100644
> index 0000000000..6d68cbeb4f
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/PlatformDxe/PlatformConfig.h
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
> new file mode 100644
> index 0000000000..d3f041ddea
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/PlatformDxe/PlatformForms.vfr
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
> new file mode 100644
> index 0000000000..1c02565ebb
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/SimicsX58PlatformConfig.h>
> +#include "Platform.h"
> +
> +formset
> + guid = SIMICSX58_PLATFORM_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 = SIMICSX58_PLATFORM_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/PlatformPei/Cmos.h
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
> new file mode 100644
> index 0000000000..616d2d74cb
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
> @@ -0,0 +1,50 @@
> +/** @file
> + PC/AT CMOS access routines
> +
> + Copyright (c) 2006 - 2009 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/PlatformPei/Platform.h
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
> new file mode 100644
> index 0000000000..5b1a9b5f57
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
> @@ -0,0 +1,93 @@
> +/** @file
> + Platform PEI module include file.
> +
> + Copyright (c) 2006 - 2016 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
> + );
> +
> +EFI_STATUS
> +PeiFvInitialization (
> + 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/PlatformPei/PlatformPei.inf
> b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
> new file mode 100644
> index 0000000000..eb8048c655
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
> @@ -0,0 +1,109 @@
> +## @file
> +# Platform PEI driver
> +#
> +# This module provides platform specific function to detect boot mode.
> +# Copyright (c) 2006 - 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = PlatformPei
> + 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
> + Fv.c
> + MemDetect.c
> + Platform.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + UefiCpuPkg/UefiCpuPkg.dec
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> + MinPlatformPkg/MinPlatformPkg.dec
> + OvmfPkg/OvmfPkg.dec
> +
> +[Guids]
> + gEfiMemoryTypeInformationGuid
> + gEfiSmmPeiSmramMemoryReserveGuid ## CONSUMES
> +
> +[LibraryClasses]
> + BaseLib
> + DebugLib
> + HobLib
> + IoLib
> + PciLib
> + PeiResourcePublicationLib
> + PeiServicesLib
> + PeiServicesTablePointerLib
> + PeimEntryPoint
> + MtrrLib
> + PcdLib
> +
> +[Pcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> + gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> + 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/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.inf
> new file mode 100644
> index 0000000000..b9bcb5d2bd
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> PolicyInitLib.inf
> @@ -0,0 +1,38 @@
> +## @file
> +#
> +# Copyright (c) 2018 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/Sil
> iconPolicyUpdateLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.inf
> new file mode 100644
> index 0000000000..da165ac947
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> iconPolicyUpdateLib.inf
> @@ -0,0 +1,35 @@
> +## @file
> +#
> +# Copyright (c) 2018 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/SimicsOpenBoardPkg.dec
> b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> new file mode 100644
> index 0000000000..17c87aca8c
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> @@ -0,0 +1,168 @@
> +## @file
> +# EFI/Framework Simics X58 platform
> +#
> +# Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + DEC_SPECIFICATION = 0x00010005
> + PACKAGE_NAME = SimicsX58Pkg
> + PACKAGE_GUID = E6A03E0D-5944-4dc6-9292-090D609EDD3A
> + PACKAGE_VERSION = 0.1
> +
> +[Includes]
> + Include
> +
> +[Guids]
> + gSimicsX58PkgTokenSpaceGuid = {0x5b276d20, 0x37d0, 0x4af0, {0x8d,
> 0x04, 0x47, 0x91, 0x2b, 0x7c, 0x1d, 0x44}}
> + gSimicsX58PlatformConfigGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a,
> 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
> +
> +[Protocols]
> + gEfiLegacy8259ProtocolGuid = {0x38321dba, 0x4fe0, 0x4e17, {0x8a,
> 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1}}
> + gEfiIsaAcpiProtocolGuid = {0x64a892dc, 0x5561, 0x4536, {0x92, 0xc7,
> 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55}}
> + gEfiIsaIoProtocolGuid = {0x7ee2bd44, 0x3da0, 0x11d4, {0x9a, 0x38,
> 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
> +
> +[PcdsFixedAtBuild]
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase|0x0|UINT32|0
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize|0x0|UINT32|1
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase|0x0|UINT32|0x15
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize|0x0|UINT32|0x16
> +
> + #TODO: Remove these two when we integrate new PlatformPei
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvBase|0x00800000|UINT32|2
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvSize|0x00500000|UINT32|3
> +
> + ## 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
> +
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase|0x0|UI
> NT32|0x8
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize|0x0|UI
> NT32|0x9
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareFdSize|0x0|UINT32|0xa
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareBlockSize|0|UINT32|0xb
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase|0x0|UI
> NT32|0xc
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase|0x0|UI
> NT32|0xd
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase|0x0
> |UINT32|0xe
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFdBaseAddress|0x0|UINT32|0xf
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase|0x0|UINT32|0x1
> 1
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesSize|0x0|UINT32|0x1
> 2
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|0x0|UINT32|0
> x13
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize|0x0|UINT32|0x
> 14
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase|0x0|UINT32|0x
> 18
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize|0x0|UINT32|0x
> 19
> +
> gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT3
> 2|0x1a
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd|0x0|UINT
> 32|0x1f
> +
> +[PcdsDynamic, PcdsDynamicEx]
> +
> + # TODO: investigate whether next two Pcds are needed
> + gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|0x28
> +
> gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEA
> N|0x10
> +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0|UINT16|0
> x1b
> +
> + ## The IO port aperture shared by all PCI root bridges.
> + #
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x23
> +
> + ## The 32-bit MMIO aperture shared by all PCI root bridges.
> + #
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT64|0x24
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT64|0x25
> +
> + ## The 64-bit MMIO aperture shared by all PCI root bridges.
> + #
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x26
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x27
> +
> +[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|0x1
> e
> +
> +
> +[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|UIN
> T16|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|0x0
> 0000003
> +
> + ## 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|0x0
> 0000004
> +
> + ## 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|BOOLE
> AN|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|0
> x00000007
> +
> + ## 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|0
> x00000008
> +
> +[PcdsFixedAtBuild, PcdsPatchableInModule]
> + ## FFS filename to find the shell application.
> + # @Prompt FFS Name of Shell Application
> + gSimicsX58PkgTokenSpaceGuid.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 |
> (gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures & 0xF8) == 0
> +
> gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0x0
> 0010040
> \ No newline at end of file
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .h
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .h
> new file mode 100644
> index 0000000000..38a71a3527
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .h
> @@ -0,0 +1,38 @@
> +/** @file
> + This driver installs SMBIOS information for OVMF
> +
> + 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..6adaf0beb7
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> .inf
> @@ -0,0 +1,51 @@
> +## @file
> +# This driver installs SMBIOS information for OVMF
> +#
> +# 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/SimicsOpenBoardPkg.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 [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 6/7] SimicsOpenBoardPkg: Add board module for QSP Build tip
2019-08-20 1:04 ` Kubacki, Michael A
@ 2019-08-23 17:04 ` David Wei
2019-08-26 22:59 ` Kubacki, Michael A
0 siblings, 1 reply; 37+ messages in thread
From: David Wei @ 2019-08-23 17:04 UTC (permalink / raw)
To: Kubacki, Michael A, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Hi Mike,
Please see the updates online below. Please let me know if you have any more comments.
Thanks
David
-----Original Message-----
From: Kubacki, Michael A
Sent: Monday, August 19, 2019 6:05 PM
To: Wei, David Y <david.y.wei@intel.com>; 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>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: RE: [edk2-platform patch 6/7] SimicsOpenBoardPkg: Add board module for QSP Build tip
Feedback I could not find already noted elsewhere:
1. Remove the batch build files:
- GitEdk2X58ICH10.bat
- bld.bat
- prebuild.bat
The changes must be built with the Python scripts.
Ydwei: Will use platform Logo library to replace the EDK2 logo driver in order to avoid compile error by Python scripts.
2. General comment that applies to multiple files:
Files such as "PlatformPkgBuildOption.dsc" should follow the pre-existing open board package
naming convention. For example, "OpenBoardPkgBuildOption.dsc" in KabylakeOpenBoardPkg.
Ydwei: done
3. The first commit line should be "SimicsOpenBoardPkg/BoardX58Ich10 to indicate the files relative
to their location in that board directory.
Ydwei: will do it when commit the patch.
4. Some build option macros in here seem unnecessary. For example, "PURLEY_FLAG". Can you please
check and clean this up?
Ydwei: done
5. PlatformPkgConfig.dsc: The following PCDs should not always be TRUE as they originate in the
AdvancedFeaturePkg and should only be enabled for an advanced feature boot.
- gAdvancedFeaturePkgTokenSpaceGuid.PcdNetworkEnable
- gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosEnable
Ydwei: They are required by SIMICS, and S3 resume also needed. I didn't make change.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 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-platform patch 6/7] SimicsOpenBoardPkg: 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> 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 +++++
> .../BoardX58ICH10/GitEdk2X58ICH10.bat | 75 +++++
> .../BoardInitLib/PeiBoardInitPostMemLib.inf | 36 +++
> .../Library/BoardInitLib/PeiBoardInitPreMemLib.inf | 38 +++
> .../Library/BoardInitLib/PeiX58ICH10InitLib.h | 16 ++
> .../BoardX58ICH10/PlatformPkgBuildOption.dsc | 89 ++++++
> .../BoardX58ICH10/PlatformPkgConfig.dsc | 56 ++++
> .../BoardX58ICH10/PlatformPkgPcd.dsc | 283 +++++++++++++++++++
> .../BoardX58ICH10/SimicsX58Pkg.fdf.inc | 48 ++++
> .../BoardX58ICH10/SimicsX58PkgIa32X64.dsc | 244 +++++++++++++++++
> .../BoardX58ICH10/SimicsX58PkgIa32X64.fdf | 303
> +++++++++++++++++++++
> .../BoardX58ICH10/VarStore.fdf.inc | 53 ++++
> .../Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat | 139 ++++++++++
> .../BoardX58ICH10/build_config.cfg | 31 +++
> .../SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat | 198
> ++++++++++++++
> 20 files changed, 2000 insertions(+)
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiB
> oardInitPostMemLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiB
> oardInitPreMemLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX
> 58ICH10Detect.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX
> 58ICH10InitPostMemLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX
> 58ICH10InitPreMemLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/DecomprScratchEnd.fdf.i
> nc
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiB
> oardInitPostMemLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiB
> oardInitPreMemLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX
> 58ICH10InitLib.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOption.
> dsc
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58Pkg.fdf.inc
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.ds
> c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.fdf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/VarStore.fdf.inc
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
>
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPostMemLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPostMemLib.c
> new file mode 100644
> index 0000000000..29df3d41ee
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPostMemLib.c
> @@ -0,0 +1,44 @@
> +/** @file
> + Copyright (c) 2018 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/Pe
> iBoardInitPreMemLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPreMemLib.c
> new file mode 100644
> index 0000000000..228fd696df
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPreMemLib.c
> @@ -0,0 +1,110 @@
> +/** @file
> + Copyright (c) 2018 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/Pe
> iX58ICH10Detect.c
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10Detect.c
> new file mode 100644
> index 0000000000..7305ce3181
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10Detect.c
> @@ -0,0 +1,26 @@
> +/** @file
> + Copyright (c) 2018 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/Pe
> iX58ICH10InitPostMemLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitPostMemLib.c
> new file mode 100644
> index 0000000000..002f63a434
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitPostMemLib.c
> @@ -0,0 +1,34 @@
> +/** @file
> + Copyright (c) 2018 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/Pe
> iX58ICH10InitPreMemLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitPreMemLib.c
> new file mode 100644
> index 0000000000..9f0dc91c8a
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitPreMemLib.c
> @@ -0,0 +1,111 @@
> +/** @file
> + Copyright (c) 2018 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 <IndustryStandard/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.fd
> f.inc
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/DecomprScratchEnd.fd
> f.inc
> new file mode 100644
> index 0000000000..394875f205
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/DecomprScratchEnd.fd
> f.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 +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize + 16 +
> gSimicsX58PkgTokenSpaceGuid.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) +
> gSimicsX58PkgTokenSpaceGuid.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 gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd =
> $(DECOMP_SCRATCH_BASE) + $(DECOMP_SCRATCH_SIZE)
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
> new file mode 100644
> index 0000000000..48e9c6b09d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
> @@ -0,0 +1,75 @@
> +@echo off
> +@REM @file
> +@REM Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +@REM
> +@REM SPDX-License-Identifier: BSD-2-Clause-Patent
> +@REM
> +
> +@echo off
> +
> +pushd ..\..\..\..\..\
> +
> +@REM Set WORKSPACE environment.
> +set WORKSPACE=%cd%
> +echo.
> +echo Set WORKSPACE as: %WORKSPACE%
> +echo.
> +
> +@REM Check whether Git has been installed and been added to system path.
> +git --help >nul 2>nul
> +if %ERRORLEVEL% NEQ 0 (
> + echo.
> + echo The 'git' command is not recognized.
> + echo Please make sure that Git is installed and has been added to system path.
> + echo.
> + goto :EOF
> +)
> +
> +@REM Create the Conf directory under WORKSPACE
> +if not exist %WORKSPACE%\Conf (
> + mkdir Conf
> +)
> +
> +@REM Set other environments.
> +@REM Basic Rule:
> +@REM Platform override Silicon override Core
> +@REM Source override Binary
> +
> +set PACKAGES_PATH=%WORKSPACE%\edk2-
> platforms\Platform\Intel;%WORKSPACE%\edk2-
> platforms\Silicon\Intel;%WORKSPACE%\edk2-
> platforms\Drivers;%WORKSPACE%\edk2-non-
> osi\Silicon\Intel;%WORKSPACE%\edk2;%WORKSPACE%
> +
> +set EDK_TOOLS_BIN=%WORKSPACE%\edk2-BaseTools-win32
> +
> +@if not defined PYTHON_HOME (
> + @if exist C:\Python27 (
> + set PYTHON_HOME=C:\Python27
> + )
> +)
> +
> +set EDK_SETUP_OPTION=
> +@rem if python is installed, disable the binary base tools.
> +if defined PYTHON_HOME (
> + set EDK_TOOLS_BIN=
> + set EDK_SETUP_OPTION=Rebuild
> +)
> +pushd %WORKSPACE%\edk2
> +call edksetup.bat %EDK_SETUP_OPTION%
> +popd
> +
> +set openssl_path=%WORKSPACE%
> +
> +popd
> +
> +goto :EOF
> +
> +:Help
> +echo.
> +echo Usage:
> +echo GitEdk2.bat [-w Workspace_Directory] (optional) [-b Branch_Name]
> (optional)
> +echo.
> +echo -w A absolute/relative path to be the workspace.
> +echo Default value is the current directory.
> +echo.
> +echo -b The branch name of the repository. Currently, only master, udk2015,
> +echo trunk (same as master) and bp13 (same as udk2015) are supported.
> +echo Default value is master.
> +echo.
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPostMemLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPostMemLib.inf
> new file mode 100644
> index 0000000000..542b53547f
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPostMemLib.inf
> @@ -0,0 +1,36 @@
> +## @file
> +#
> +# Copyright (c) 2018 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/Pe
> iBoardInitPreMemLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPreMemLib.inf
> new file mode 100644
> index 0000000000..ab1286602b
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iBoardInitPreMemLib.inf
> @@ -0,0 +1,38 @@
> +## @file
> +#
> +# Copyright (c) 2018 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/SimicsOpenBoardPkg.dec
> +
> +[Sources]
> + PeiX58ICH10Detect.c
> + PeiX58ICH10InitPreMemLib.c
> + PeiBoardInitPreMemLib.c
> +
> +[Pcd]
> +
> +[FixedPcd]
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitLib.h
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitLib.h
> new file mode 100644
> index 0000000000..996679e8f5
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> iX58ICH10InitLib.h
> @@ -0,0 +1,16 @@
> +/** @file
> + Copyright (c) 2018 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/PlatformPkgBuildOptio
> n.dsc
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOptio
> n.dsc
> new file mode 100644
> index 0000000000..8bce3c7a4f
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOptio
> n.dsc
> @@ -0,0 +1,89 @@
> +## @file
> +#
> +# Copyright (c) 2018 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 CRB_EDKII_BUILD_OPTIONS = -D CRB_FLAG
> + DEFINE EDKII_CPU_BUILD_OPTIONS = -D PURLEY_FLAG
> + DEFINE TRAD_BUILD_OPTION = -D TRAD_FLAG=1
> + DEFINE SUS_WELL_RESTORE_BUILD_OPTION = -D SUS_WELL_RESTORE=1
> + DEFINE PCH_BUILD_OPTION = -D PCH_SERVER_BIOS_FLAG=1
> + DEFINE SERVER_BUILD_OPTION = -D SERVER_BIOS_FLAG=1
> + DEFINE PCH_PKG_OPTIONS = -D PCH_SPT
> + DEFINE MAX_SOCKET_OPTIONS = -D MAX_SOCKET=2
> +
> + DEFINE EDKII_ALL_PPO_OPTIONS = $(EDKII_CPU_BUILD_OPTIONS)
> + DEFINE PCH_BIOS_BUILD_OPTIONS = $(TRAD_BUILD_OPTION)
> $(ULT_BUILD_OPTION) $(PCH_BUILD_OPTION)
> $(SUS_WELL_RESTORE_BUILD_OPTION) $(SERVER_BUILD_OPTION)
> + DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS =
> $(CRB_EDKII_BUILD_OPTIONS) $(PCH_BIOS_BUILD_OPTIONS)
> $(PCH_PKG_OPTIONS) $(EDKII_ALL_PPO_OPTIONS)
> $(SPARING_SCRATCHPAD_OPTION) $(TRACE_HUB_DEBUG_BUILD_OPTIONS)
> $(TRACE_HUB_INIT_BUILD_OPTIONS) $(MAX_SOCKET_OPTIONS) -D
> EFI_PCI_IOV_SUPPORT -D WHEA_SUPPORT -D SKX_HOST -D CLX_HOST
> +
> +!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/PlatformPkgConfig.dsc
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
> new file mode 100644
> index 0000000000..f0ab846290
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
> @@ -0,0 +1,56 @@
> +## @file
> +#
> +# Copyright (c) 2018 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/PlatformPkgPcd.dsc
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
> new file mode 100644
> index 0000000000..dc70adee34
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
> @@ -0,0 +1,283 @@
> +## @file
> +#
> +# Copyright (c) 2018 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.PcdResetOnMemoryTypeInformationChan
> ge|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|0x17000
> 00
> +
> + 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|0x200910
> 13
> +
> + ## 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.PcdResetOnMemoryTypeInformationChan
> ge|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
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress|0xFFE00000
> + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize|0x00200000
> +
> +[PcdsDynamicExDefault.common.DEFAULT]
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|30000
> + gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress|0
> +
> +[PcdsDynamicExHii.common.DEFAULT]
> +
> gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobal
> VariableGuid|0x0|50 # Variable: L"Timeout"
> +
> gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSuppo
> rt"|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|0x204657303
> 0363253
> +
> +[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|0x800
> 0
> + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xc000
> + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0xc000
> +
> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x200
> 0
> +
> 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
> +
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase|0x0
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize|0x0
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base|0x0
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size|0x0
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base|0x0
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size|0x800000000
> +
> +
> gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0StringBiosVersion|"Ve
> r.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/SimicsX58Pkg.fdf.inc
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58Pkg.fdf.inc
> new file mode 100644
> index 0000000000..f42e8b0e0e
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58Pkg.fdf.inc
> @@ -0,0 +1,48 @@
> +## @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 gSimicsX58PkgTokenSpaceGuid.PcdSimicsFdBaseAddress =
> $(FW_BASE_ADDRESS)
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareFdSize = $(FW_SIZE)
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareBlockSize =
> $(BLOCK_SIZE)
> +
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase =
> $(FW_BASE_ADDRESS)
> +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize =
> 0xE000
> +
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase =
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase +
> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize =
> $(BLOCK_SIZE)
> +
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase
> = gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize
> +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize =
> $(BLOCK_SIZE)
> +
> +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase =
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase +
> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize =
> 0x10000
> +
> +DEFINE MEMFD_BASE_ADDRESS = 0x800000
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.
> dsc
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.
> dsc
> new file mode 100644
> index 0000000000..66ac16a940
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.
> dsc
> @@ -0,0 +1,244 @@
> +## @file
> +#
> +# Copyright (c) 2018 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)/SimicsX58PkgIa32X64.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)/PlatformPkgConfig.dsc
> + !include MinPlatformPkg/Include/Dsc/CoreCommonLib.dsc
> + !include $(PCH_PKG)/PchCommonLib.dsc
> +
> +[LibraryClasses]
> +
> ReportFvLib|MinPlatformPkg/PlatformInit/Library/PeiReportFvLib/PeiReportFv
> Lib.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/SerializeVari
> ablesLib.inf
> + LoadLinuxLib|$(BOARD_PKG)/Library/LoadLinuxLib/LoadLinuxLib.inf
> +
> CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/
> CpuExceptionHandlerLibNull.inf
> +
> +
> TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLibNull/TestPoi
> ntCheckLibNull.inf
> +
> BoardInitLib|MinPlatformPkg/PlatformInit/Library/BoardInitLibNull/BoardInitLi
> bNull.inf
> +
> SiliconPolicyInitLib|$(BOARD_PKG)/Policy/Library/SiliconPolicyInitLib/SiliconPol
> icyInitLib.inf
> +
> SiliconPolicyUpdateLib|$(BOARD_PKG)/Policy/Library/SiliconPolicyUpdateLib/S
> iliconPolicyUpdateLib.inf
> +
> PciSegmentInfoLib|MinPlatformPkg/Pci/Library/PciSegmentInfoLibSimple/PciS
> egmentInfoLibSimple.inf
> +
> + !include MinPlatformPkg/Include/Dsc/CorePeiLib.dsc
> +
> +
> S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScri
> ptLib.inf
> +
> AslUpdateLib|MinPlatformPkg/Acpi/Library/DxeAslUpdateLib/DxeAslUpdateLib.
> inf
> +[LibraryClasses.common.SEC]
> +
> ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExt
> ractGuidedSectionLib.inf
> +
> +[LibraryClasses.common.PEI_CORE]
> +
> +[LibraryClasses.common.PEIM]
> +
> PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiReso
> urcePublicationLib.inf
> + MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
> +
> +[LibraryClasses.IA32]
> +!if $(TARGET) == DEBUG
> +
> TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLib/PeiTestPoi
> ntCheckLib.inf
> +!endif
> + TestPointLib|MinPlatformPkg/Test/Library/TestPointLib/PeiTestPointLib.inf
> +
> + !include MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc
> +
> +[LibraryClasses.common.DXE_CORE]
> +
> +[LibraryClasses.common.DXE_RUNTIME_DRIVER]
> +
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> Ich10.inf
> +
> +[LibraryClasses.common.UEFI_DRIVER]
> +
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> Ich10.inf
> +
> +[LibraryClasses.common.DXE_DRIVER]
> +
> PlatformBootManagerLib|$(BOARD_PKG)/Overrides/MdeModulePkg/Library/P
> latformBootManagerLib/PlatformBootManagerLib.inf
> +
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> Ich10.inf
> +
> +[LibraryClasses.common.UEFI_APPLICATION]
> +
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> Ich10.inf
> +
> +[LibraryClasses.common.DXE_SMM_DRIVER]
> +
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> Ich10.inf
> +
> SpiFlashCommonLib|$(PCH_PKG)/Library/SmmSpiFlashCommonLib/SmmSpiFla
> shCommonLib.inf
> +
> +[LibraryClasses.common.SMM_CORE]
> +
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> Ich10.inf
> +
> + !include $(BOARD_PKG)/$(BOARD_NAME)/PlatformPkgPcd.dsc
> +
> +[Components.IA32]
> + !include $(SKT_PKG)/SktPei.dsc
> + !include MinPlatformPkg/Include/Dsc/CorePeiInclude.dsc
> +
> + $(BOARD_PKG)/PlatformPei/PlatformPei.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/PeiBoardI
> nitPreMemLib.inf
> + }
> + MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf {
> + <LibraryClasses>
> +
> BoardInitLib|$(BOARD_PKG)/$(BOARD_NAME)/Library/BoardInitLib/PeiBoardI
> nitPostMemLib.inf
> + }
> + MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf
> + MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf
> +
> +[Components.X64]
> + !include MinPlatformPkg/Include/Dsc/CoreDxeInclude.dsc
> +
> $(BOARD_PKG)/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.i
> nf
> + !include AdvancedFeaturePkg/Include/Dsc/CoreAdvancedDxeInclude.dsc
> +
> + MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
> + $(BOARD_PKG)/Overrides/MdeModulePkg/Logo/LogoDxe.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)/PlatformDxe/Platform.inf
> + MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
> +
> MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.
> inf
> +
> + #
> + # Shell
> + #
> + ShellPkg/Application/Shell/Shell.inf {
> + <PcdsFixedAtBuild>
> + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> + <LibraryClasses>
> +
> NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2Command
> sLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1Command
> sLib.inf
> +
> NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3Command
> sLib.inf
> +
> NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1Comman
> dsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1Comma
> ndsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1Co
> mmandsLib.inf
> +
> NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Co
> mmandsLib.inf
> +
> ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLi
> b.inf
> +
> HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.
> inf
> +
> BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCo
> mmandLib.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)/Overrides/MdeModulePkg/Library/PciHostBr
> idgeLib/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)/PlatformPkgBuildOption.dsc
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.f
> df
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.f
> df
> new file mode 100644
> index 0000000000..d6c381a515
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.f
> df
> @@ -0,0 +1,303 @@
> +## @file
> +#
> +# Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +!include SimicsX58Pkg.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|gEfi
> MdeModulePkgTokenSpaceGuid.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|gEfiMd
> eModulePkgTokenSpaceGuid.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
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase|gSimicsX58PkgT
> okenSpaceGuid.PcdSimicsSecPageTablesSize
> +
> +0x006000|0x001000
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase|gSimicsX58Pkg
> TokenSpaceGuid.PcdSimicsLockBoxStorageSize
> +
> +0x007000|0x001000
> +gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gSimicsX
> 58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> +
> +0x010000|0x008000
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|gSimicsX58Pk
> gTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> +
> +0x020000|0x0E0000
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase|gSimicsX58PkgToke
> nSpaceGuid.PcdSimicsPeiMemFvSize
> +FV = FvPreMemory
> +
> +0x100000|0xA00000
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase|gSimicsX58PkgTok
> enSpaceGuid.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
> +
> +!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)/PchPreMemoryInclude.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)/PlatformPei/PlatformPei.inf
> +!include $(SKT_PKG)/SktPostMemoryInclude.fdf
> +!include $(PCH_PKG)/PchPostMemoryInclude.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
> +INF
> $(BOARD_PKG)/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.i
> nf
> +!include $(SKT_PKG)/SktUefiBootInclude.fdf
> +!include $(PCH_PKG)/PchUefiBootInclude.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 $(BOARD_PKG)/Overrides/MdeModulePkg/Logo/LogoDxe.inf
> +INF MinPlatformPkg/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
> +INF MinPlatformPkg/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
> +INF $(BOARD_PKG)/PlatformDxe/Platform.inf
> +
> +INF ShellPkg/Application/Shell/Shell.inf
> +
> +#
> +# Network modules
> +#
> +FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 {
> + SECTION PE32 = SimicsICH10SiliconBinPkg/UndiBinary/GigUndiDxe.efi
> + SECTION UI = "IntelIch10UNDI"
> +}
> +!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/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|gEfiMde
> ModulePkgTokenSpaceGuid.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/bld.bat
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
> new file mode 100644
> index 0000000000..efce310dfe
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
> @@ -0,0 +1,139 @@
> +@echo off
> +@REM @file
> +@REM Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +@REM
> +@REM SPDX-License-Identifier: BSD-2-Clause-Patent
> +@REM
> +
> +@echo off
> +
> +REM Run setlocal to take a snapshot of the environment variables. endlocal is
> called to restore the environment.
> +setlocal
> +set SCRIPT_ERROR=0
> +
> +REM ---- Do NOT use :: for comments Inside of code blocks() ----
> +
> +::***********************************************************
> ***********
> +:: Initial Setup
> +::***********************************************************
> ***********
> +
> +:parseCmdLine
> +if "%1"=="" goto :argumentCheck
> +
> +if /I "%1"=="debug" set TARGET=DEBUG
> +if /I "%1"=="release" set TARGET=RELEASE
> +
> +if /I "%1"=="cleantree" (
> + set BUILD_TYPE=cleantree
> + call :cleantree
> + goto :EOF
> +)
> +
> +shift
> +GOTO :parseCmdLine
> +
> +:argumentCheck:
> +
> +if /I "%TARGET%" == "" (
> + echo Info: debug/release argument is empty, use DEBUG as default
> + set TARGET=DEBUG
> +)
> +
> +REM Art to notify which board you're working on
> +echo.
> +type logo.txt
> +echo.
> +
> +::
> +:: Build configuration
> +::
> +set BUILD_REPORT_FLAGS=
> +set BUILD_CMD_LINE=
> +set BUILD_LOG=%WORKSPACE%\Build\BuildSrc\build.log
> +set BUILD_REPORT=%WORKSPACE%\Build\BuildSrc\BuildReport.txt
> +
> +del %BUILD_LOG% *.efi *.log 2>NUL
> +
> +echo --------------------------------------------------------------------------------------------
> +echo.
> +echo QSP Build Start
> +echo.
> +echo --------------------------------------------------------------------------------------------
> +
> +
> +:doPreBuild
> +echo.
> +echo --------------------------------------------------------------------
> +echo.
> +echo Prebuild Start
> +echo.
> +echo --------------------------------------------------------------------
> +call prebuild.bat
> +if %SCRIPT_ERROR% NEQ 0 EXIT /b %ERRORLEVEL%
> +
> +echo --------------------------------------------------------------------
> +echo.
> +echo Prebuild End
> +echo.
> +echo --------------------------------------------------------------------
> +if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
> +timeout 1
> +
> +:buildBios
> +set BUILD_CMD_LINE=%BUILD_CMD_LINE% -D
> MAX_SOCKET=%MAX_SOCKET% -y %BUILD_REPORT%
> +echo --------------------------------------------------------------------
> +echo.
> +echo Build Start
> +echo.
> +echo --------------------------------------------------------------------
> +echo.
> +echo build %BUILD_CMD_LINE% --log=%BUILD_LOG%
> %BUILD_REPORT_FLAGS%
> +call build %BUILD_CMD_LINE% --log=%BUILD_LOG%
> %BUILD_REPORT_FLAGS%
> +echo --------------------------------------------------------------------
> +echo.
> +echo Build End
> +echo.
> +echo --------------------------------------------------------------------
> +if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
> +timeout 1
> +
> +:postBuild
> +
> +echo --------------------------------------------------------------------
> +echo.
> +echo PostBuild Start
> +echo.
> +echo --------------------------------------------------------------------
> +echo.
> +REM call postbuild.bat
> +if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
> +timeout 1
> +echo --------------------------------------------------------------------
> +echo.
> +echo PostBuild End
> +echo.
> +echo --------------------------------------------------------------------
> +
> +echo %date% %time%
> +echo.
> +
> +echo --------------------------------------------------------------------------------------------
> +echo.
> +echo QSP Build End
> +echo.
> +echo --------------------------------------------------------------------------------------------
> +
> +:done
> +endlocal & EXIT /b %SCRIPT_ERROR%
> +
> +::--------------------------------------------------------
> +::-- Function section starts below here
> +::--------------------------------------------------------
> +:cleantree
> +choice /t 3 /d y /m "Confirm: clean tree of intermediate files created in tree
> during build"
> +if %ERRORLEVEL% EQU 2 goto :EOF
> +goto :EOF
> +
> +
> +:ErrorHandler:
> +echo Error handler
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
> new file mode 100644
> index 0000000000..ad3ae229e8
> --- /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 = WORKSPACE_PLATFORM_BIN
> +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/SimicsX58PkgIa32X64.dsc
> +BOARD_PKG_PCD_DSC =
> SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.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
> diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
> new file mode 100644
> index 0000000000..666332e2d4
> --- /dev/null
> +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
> @@ -0,0 +1,198 @@
> +@echo off
> +@REM @file
> +@REM Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> +@REM
> +@REM SPDX-License-Identifier: BSD-2-Clause-Patent
> +@REM
> +
> +@set SCRIPT_ERROR=0
> +
> +set /a prebuildstep=0
> +
> +call :check_BuildTools
> +if %SCRIPT_ERROR% NEQ 0 GOTO :done
> +
> +call :setBuildEnv
> +if %SCRIPT_ERROR% NEQ 0 GOTO :done
> +
> +call :createTargetTxt
> +if %SCRIPT_ERROR% NEQ 0 GOTO :done
> +
> +REM call :genPlatformOffsetHeaderFile
> +REM if %SCRIPT_ERROR% NEQ 0 GOTO :done
> +
> +:prebuildFinish
> +echo.
> +echo ACTIVE_PLATFORM = %WORKSPACE%\edk2-
> platforms\Platform\Intel\%BOARD_PKG%\%BOARD_NAME%\SimicsX58PkgIa3
> 2X64.dsc
> +echo EDK_TOOLS_PATH = %EDK_TOOLS_PATH%
> +echo TARGET = %TARGET%
> +echo TARGET_ARCH = IA32 X64
> +echo TOOL_CHAIN_TAG = %TOOL_CHAIN_TAG%
> +echo WORKSPACE = %WORKSPACE%
> +echo PACKAGES_PATH = %PACKAGES_PATH%
> +echo MAX_CONCURRENT_THREAD_NUMBER =
> %BUILD_MAX_CON_THREAD_NUM%
> +echo.
> +echo Build Path = %OUTPUT_DIR%
> +echo.
> +
> +REM Remove environment variable because it's no longer needed.
> +set BUILD_MAX_CON_THREAD_NUM=
> +
> +:done
> +REM Use done label to exit batch file and run any final steps; GOTO :EOF
> immediately exits.
> +EXIT /B %SCRIPT_ERROR%
> +
> +::--------------------------------------------------------
> +::-- Function section starts below here
> +::--------------------------------------------------------
> +
> +:cleanup_check_VSTools
> +set COMPILER_VERSION_STRING=
> +del cloutput.txt > nul
> +REM cleanup_check_VSTools is called below. When a label is called, 'GOTO
> :EOF' is used to return to caller.
> +GOTO :EOF
> +
> +:check_BuildTools
> +echo PreBuild.%prebuildstep% check_BuildTools
> +echo ..VSTools
> +set /a prebuildstep=%prebuildstep%+1
> +set TOOL_CHAIN_TAG=
> +@if not defined TOOL_CHAIN_TAG (
> + echo.
> + echo Prebuild: TOOL_CHAIN_TAG is not set before
> + echo.
> +
> + @if defined VS140COMNTOOLS (
> + echo.
> + echo Set the VS2015 environment.
> + echo.
> + set CL_SEL=VS2015
> + if /I "%VS140COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio
> 14.0\Common7\Tools\" (
> + set TOOL_CHAIN_TAG=VS2015
> + ) else (
> + set TOOL_CHAIN_TAG=VS2015x86
> + )
> + if /I "%PROCESSOR_ARCHITECTURE%" == "AMD64" (
> + set CL_CMDLINE="%VS140COMNTOOLS:~0,-14%VC\bin\amd64\cl.exe"
> + ) else (
> + set CL_CMDLINE="%VS140COMNTOOLS:~0,-14%VC\bin\cl.exe"
> + )
> + ) else if defined VS120COMNTOOLS (
> + echo.
> + echo Set the VS2013 environment.
> + echo.
> + set CL_SEL=VS2013
> + if /I "%VS120COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio
> 12.0\Common7\Tools\" (
> + set TOOL_CHAIN_TAG=VS2013
> + ) else (
> + set TOOL_CHAIN_TAG=VS2013x86
> + )
> + if /I "%PROCESSOR_ARCHITECTURE%" == "AMD64" (
> + set CL_CMDLINE="%VS120COMNTOOLS:~0,-14%VC\bin\amd64\cl.exe"
> + ) else (
> + set CL_CMDLINE="%VS120COMNTOOLS:~0,-14%VC\bin\cl.exe"
> + )
> + ) else (
> + echo.
> + echo !!! ERROR !!! VS2015 or VS2013 not installed correctly. !!!
> + echo.
> + goto :ErrorExit
> + )
> +)
> +
> +echo ..iASL
> +set CHECK_PATH_IASL=%IASL_PREFIX%
> +if not exist %CHECK_PATH_IASL%\iasl.exe (
> + echo.
> + echo !!! ERROR !!! Could not find iASL compiler at
> %CHECK_PATH_IASL%\iasl.exe. !!!
> + echo.
> + set SCRIPT_ERROR=1
> +)
> +set CHECK_PATH_IASL=
> +
> +echo ..NASM
> +set CHECK_PATH_NASM=c:\NASM
> +if not exist %CHECK_PATH_NASM%\nasm.exe (
> + echo.
> + echo !!! ERROR !!! Could not find NASM compiler at
> %CHECK_PATH_NASM%\nasm.exe. !!!
> + echo.
> + set SCRIPT_ERROR=1
> +)
> +set CHECK_PATH_NASM=
> +
> +echo ..Python
> +set CHECK_PATH_PYTHON=c:\Python27
> +if not exist %CHECK_PATH_PYTHON%\python.exe (
> + echo.
> + echo !!! ERROR !!! Could not find Python at
> %CHECK_PATH_PYTHON%\python.exe. !!!
> + echo.
> + set SCRIPT_ERROR=1
> +)
> +set CHECK_PATH_PYTHON=
> +set PYTHON_HOME=C:\Python27
> +
> +GOTO :EOF
> +
> +:setBuildEnv
> +echo PreBuild.%prebuildstep% SetBuildEnv
> +set /a prebuildstep=%prebuildstep%+1
> +
> +@set BOARD_PKG=SimicsOpenBoardPkg
> +@set BOARD_NAME=BoardX58ICH10
> +@set MAX_SOCKET=2
> +
> +echo.
> +echo BOARD_NAME=%BOARD_NAME%
> +echo BOARD_PKG=%BOARD_PKG%
> +echo MAX_SOCKET=%MAX_SOCKET%
> +echo TARGET=%TARGET%
> +
> +@set
> OUTPUT_DIR=%WORKSPACE%\Build\BuildSrc\%BOARD_PKG%\%BOARD_NAM
> E%\%TARGET%_%TOOL_CHAIN_TAG%
> +
> +if not exist %OUTPUT_DIR% mkdir %OUTPUT_DIR%
> +GOTO :EOF
> +
> +:createTargetTxt
> +echo PreBuild.%prebuildstep% CreateTargetTxt
> +set /a prebuildstep=%prebuildstep%+1
> +set /a BUILD_MAX_CON_THREAD_NUM = %NUMBER_OF_PROCESSORS%-1
> +@REM set /a BUILD_MAX_CON_THREAD_NUM = 1
> +findstr /V "ACTIVE_PLATFORM TARGET TARGET_ARCH TOOL_CHAIN_TAG
> BUILD_RULE_CONF MAX_CONCURRENT_THREAD_NUMBER"
> %WORKSPACE%\Conf\target.txt > %OUTPUT_DIR%\target.txt 2>NUL
> +echo ACTIVE_PLATFORM = %WORKSPACE%/edk2-
> platforms/Platform/Intel/%BOARD_PKG%/%BOARD_NAME%/SimicsX58PkgIa3
> 2X64.dsc >> %OUTPUT_DIR%\target.txt
> +echo TARGET = %TARGET% >>
> %OUTPUT_DIR%\target.txt
> +echo TARGET_ARCH = IA32 X64 >>
> %OUTPUT_DIR%\target.txt
> +echo TOOL_CHAIN_TAG = %TOOL_CHAIN_TAG% >>
> %OUTPUT_DIR%\target.txt
> +echo BUILD_RULE_CONF = Conf/build_rule.txt >>
> %OUTPUT_DIR%\target.txt
> +echo MAX_CONCURRENT_THREAD_NUMBER =
> %BUILD_MAX_CON_THREAD_NUM% >> %OUTPUT_DIR%\target.txt
> +if exist %WORKSPACE%\Conf\target.txt (
> + del /f %WORKSPACE%\Conf\target.txt
> +)
> +move /Y %OUTPUT_DIR%\target.txt %WORKSPACE%\Conf\ > nul
> +if not exist %OUTPUT_DIR%\X64 mkdir %OUTPUT_DIR%\X64
> +GOTO :EOF
> +
> +
> +:genPlatformOffsetHeaderFile
> +echo.
> +echo PreBuild.%prebuildstep% GenPlatformOffsetHeaderFile
> +set /a prebuildstep=%prebuildstep%+1
> +
> +echo Info: re-generating PlatformOffset header files
> +
> +set PRE_BUILD_CMD_LINE=%BUILD_CMD_LINE% -D
> MAX_SOCKET=%MAX_SOCKET%
> +set PRE_BUILD_LOG=%WORKSPACE%\Build\BuildSrc\prebuild.log
> +set PRE_BUILD_REPORT=%WORKSPACE%\Build\BuildSrc\preBuildReport.txt
> +
> +echo build %PRE_BUILD_CMD_LINE% -m
> %BOARD_PKG%\Acpi\BoardAcpiDxe\Dsdt.inf -y %PRE_BUILD_REPORT% --
> log=%PRE_BUILD_LOG%
> +call build %PRE_BUILD_CMD_LINE% -m
> %BOARD_PKG%\Acpi\BoardAcpiDxe\Dsdt.inf -y %PRE_BUILD_REPORT% --
> log=%PRE_BUILD_LOG%
> +if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
> +
> +@REM PSYS == FIX0
> +@REM MCTL == FIX8
> +set AML_FILTER="\"PSYS\" .MCTL\" .FIX[0-9,A-Z]\""
> +echo AML_FILTER=%AML_FILTER%
> +%WORKSPACE%\edk2-
> platforms\Platform\Intel\MinPlatformPkg\Tools\AmlGenOffset\AmlGenOffset.
> py -d --aml_filter %AML_FILTER% -o %WORKSPACE%\edk2-
> platforms\Platform\Intel\%BOARD_PKG%\Acpi\BoardAcpiDxe\AmlOffsetTable.
> c
> %OUTPUT_DIR%\X64\PurleyOpenBoardPkg\Acpi\BoardAcpiDxe\DSDT\OUTPU
> T\Dsdt\WFPPlatform.offset.h
> +echo.
> +echo GenOffset done
> +
> +GOTO :EOF
> --
> 2.16.2.windows.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform
2019-08-20 1:04 ` Kubacki, Michael A
@ 2019-08-23 17:06 ` David Wei
2019-08-26 23:00 ` Kubacki, Michael A
0 siblings, 1 reply; 37+ messages in thread
From: David Wei @ 2019-08-23 17:06 UTC (permalink / raw)
To: Kubacki, Michael A, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Hi Mike,
Please see the updates online below. Please let me know if you have any more comments.
Thanks
David
-----Original Message-----
From: Kubacki, Michael A
Sent: Monday, August 19, 2019 6:05 PM
To: Wei, David Y <david.y.wei@intel.com>; 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>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: RE: [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform
You will need to resolve a conflict in build.cfg. When you do so, please keep the boards under [PLATFORMS] in lexicographically ascending order for ease of maintenance.
Ydwei: done
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 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-platform patch 7/7] Platform/Intel: Add build option
> for SIMICS QSP Platform
>
> Add build option in build script for SIMICS QSP Platform
>
> 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
> Platform/Intel/build.cfg | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg index
> fc6e4fe824..2ebe09a632 100644
> --- a/Platform/Intel/build.cfg
> +++ b/Platform/Intel/build.cfg
> @@ -54,3 +54,5 @@ NUMBER_OF_PROCESSORS = 0
> KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
> N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
> BoardMtOlympus = PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
> +WhiskeylakeURvp =
> +WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
> +BoardX58ICH10 = SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
> --
> 2.16.2.windows.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
2019-08-20 1:04 ` Kubacki, Michael A
@ 2019-08-23 17:09 ` David Wei
2019-08-26 22:51 ` Kubacki, Michael A
0 siblings, 1 reply; 37+ messages in thread
From: David Wei @ 2019-08-23 17:09 UTC (permalink / raw)
To: Kubacki, Michael A, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Hi Mike,
Please see the updates online below. Please let me know if you have any more comments.
Thanks
David
-----Original Message-----
From: Kubacki, Michael A
Sent: Monday, August 19, 2019 6:05 PM
To: Wei, David Y <david.y.wei@intel.com>; 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>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: RE: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
Agree with Nate's feedback on moving the noted items out of the "Overrides" directory.
Ydwei: done
Please do submit a patch for style fixes in MinPlatformPkg/Acpi/AcpiTables directly.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 9, 2019 3:47 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-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides
> modules for SIMICS QSP Platform
>
> Overrides/MdeModulePkg/Library/PciHostBridgeLib - it is platform related.
> should be Customized
> Overrides/MdeModulePkg/Logo - the Logo image is Customized
> Overrides/MdePkg/Library/BasePciLibCf8 - use the functions specific for SIMICS
>
> 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>
> Contributed-under: TianoCore Contribution Agreement 1.0
>
> Signed-off-by: David Wei <david.y.wei@intel.com>
> ---
> .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++
> .../Library/PlatformBootManagerLib/BdsPlatform.c | 1553
> +++++++++++++++++++
> .../Library/PlatformBootManagerLib/PlatformData.c | 35 +
> .../Overrides/MdeModulePkg/Logo/Logo.c | 154 ++
> .../MdePkg/Library/BasePciLibCf8/PciLib.c | 1221 +++++++++++++++
> .../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 | 417 ++++++
> .../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++
> .../8259InterruptControllerDxe/8259.c | 622 ++++++++
> .../Library/PciHostBridgeLib/PciHostBridge.h | 68 +
> .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 50 +
> .../Library/PlatformBootManagerLib/BdsPlatform.h | 156 ++
> .../PlatformBootManagerLib.inf | 69 +
> .../Overrides/MdeModulePkg/Logo/Logo.bmp | Bin 0 -> 141078 bytes
> .../Overrides/MdeModulePkg/Logo/Logo.idf | 10 +
> .../Overrides/MdeModulePkg/Logo/Logo.inf | 28 +
> .../Overrides/MdeModulePkg/Logo/Logo.uni | 16 +
> .../Overrides/MdeModulePkg/Logo/LogoDxe.inf | 55 +
> .../Overrides/MdeModulePkg/Logo/LogoDxe.uni | 16 +
> .../Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni | 14 +
> .../Overrides/MdeModulePkg/Logo/LogoExtra.uni | 14 +
> .../Library/BasePciLibCf8/DxePciLibX58Ich10.inf | 40 +
> .../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 +
> .../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++
> .../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++
> .../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 73 +
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 281 ++++
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++
> .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 +
> .../8259InterruptControllerDxe/8259.h | 218 +++
> .../8259InterruptControllerDxe/8259.inf | 46 +
> .../8259InterruptControllerDxe/Legacy8259.uni | 16 +
> .../8259InterruptControllerDxe/Legacy8259Extra.uni | 14 +
> 41 files changed, 11062 insertions(+)
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHos
> tBridgeLib/PciHostBridgeLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/BdsPlatform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/PlatformData.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/
> PciLib.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/AcpiPlatform.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Facs/Facs.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Fadt/Fadt.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Hpet/Hpet.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/Wsmt/Wsmt.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Com
> ponentName.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driv
> er.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Driv
> erSupportedEfiVersion.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Gop.
> c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Initia
> lize.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/8259.c
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHos
> tBridgeLib/PciHostBridge.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciHos
> tBridgeLib/PciHostBridgeLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/BdsPlatform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platfor
> mBootManagerLib/PlatformBootManagerLib.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.bm
> p
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.idf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.
> inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe.
> uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoDxe
> Extra.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoExtr
> a.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf8/
> DxePciLibX58Ich10.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/AcpiPlatform.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTabl
> es/AcpiPlatform.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qem
> u.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qem
> uVideoDxe.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.asm
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/VbeS
> him.sh
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/8259.h
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/8259.inf
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/Legacy8259.uni
> create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interrupt
> ControllerDxe/Legacy8259Extra.uni
>
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.c
> new file mode 100644
> index 0000000000..2aaa4b3e90
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.c
> @@ -0,0 +1,419 @@
> +/** @file
> + OVMF'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 <IndustryStandard/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/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.c
> new file mode 100644
> index 0000000000..0b66862e46
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.c
> @@ -0,0 +1,1553 @@
> +/** @file
> + Platform BDS customizations.
> +
> + Copyright (c) 2004 - 2018 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
> + //
> + BootLogoEnableLogo();
> +
> + 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/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformData.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformData.c
> new file mode 100644
> index 0000000000..5f1b16dd56
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/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 - 2017 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/Overrides/MdeModulePkg/Logo/Logo.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
> new file mode 100644
> index 0000000000..d4a75ad140
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.c
> @@ -0,0 +1,154 @@
> +/** @file
> + Logo DXE Driver, install Edkii Platform Logo protocol.
> +
> + Copyright (c) 2016 - 2017 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Uefi.h>
> +#include <Protocol/HiiDatabase.h>
> +#include <Protocol/GraphicsOutput.h>
> +#include <Protocol/HiiImageEx.h>
> +#include <Protocol/PlatformLogo.h>
> +#include <Protocol/HiiPackageList.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +
> +typedef struct {
> + EFI_IMAGE_ID ImageId;
> + EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE Attribute;
> + INTN OffsetX;
> + INTN OffsetY;
> +} LOGO_ENTRY;
> +
> +EFI_HII_IMAGE_EX_PROTOCOL *mHiiImageEx;
> +EFI_HII_HANDLE mHiiHandle;
> +LOGO_ENTRY mLogos[] = {
> + {
> + IMAGE_TOKEN (IMG_LOGO),
> + EdkiiPlatformLogoDisplayAttributeCenter,
> + 0,
> + 0
> + }
> +};
> +
> +/**
> + Load a platform logo image and return its data and attributes.
> +
> + @param This The pointer to this protocol instance.
> + @param Instance The visible image instance is found.
> + @param Image Points to the image.
> + @param Attribute The display attributes of the image returned.
> + @param OffsetX The X offset of the image regarding the Attribute.
> + @param OffsetY The Y offset of the image regarding the Attribute.
> +
> + @retval EFI_SUCCESS The image was fetched successfully.
> + @retval EFI_NOT_FOUND The specified image could not be found.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetImage (
> + IN EDKII_PLATFORM_LOGO_PROTOCOL *This,
> + IN OUT UINT32 *Instance,
> + OUT EFI_IMAGE_INPUT *Image,
> + OUT EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE *Attribute,
> + OUT INTN *OffsetX,
> + OUT INTN *OffsetY
> + )
> +{
> + UINT32 Current;
> + if (Instance == NULL || Image == NULL ||
> + Attribute == NULL || OffsetX == NULL || OffsetY == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Current = *Instance;
> + if (Current >= ARRAY_SIZE (mLogos)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + (*Instance)++;
> + *Attribute = mLogos[Current].Attribute;
> + *OffsetX = mLogos[Current].OffsetX;
> + *OffsetY = mLogos[Current].OffsetY;
> + return mHiiImageEx->GetImageEx (mHiiImageEx, mHiiHandle,
> mLogos[Current].ImageId, Image);
> +}
> +
> +EDKII_PLATFORM_LOGO_PROTOCOL mPlatformLogo = {
> + GetImage
> +};
> +
> +/**
> + Entrypoint of this module.
> +
> + This function is the entrypoint of this module. It installs the Edkii
> + Platform Logo protocol.
> +
> + @param ImageHandle The firmware allocated handle for the EFI image.
> + @param SystemTable A pointer to the EFI System Table.
> +
> + @retval EFI_SUCCESS The entry point is executed successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeLogo (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> + EFI_HII_PACKAGE_LIST_HEADER *PackageList;
> + EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
> + EFI_HANDLE Handle;
> +
> + Status = gBS->LocateProtocol (
> + &gEfiHiiDatabaseProtocolGuid,
> + NULL,
> + (VOID **) &HiiDatabase
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + Status = gBS->LocateProtocol (
> + &gEfiHiiImageExProtocolGuid,
> + NULL,
> + (VOID **) &mHiiImageEx
> + );
> + ASSERT_EFI_ERROR (Status);
> +
> + //
> + // Retrieve HII package list from ImageHandle
> + //
> + Status = gBS->OpenProtocol (
> + ImageHandle,
> + &gEfiHiiPackageListProtocolGuid,
> + (VOID **) &PackageList,
> + ImageHandle,
> + NULL,
> + EFI_OPEN_PROTOCOL_GET_PROTOCOL
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "HII Image Package with logo not found in
> PE/COFF resource section\n"));
> + return Status;
> + }
> +
> + //
> + // Publish HII package list to HII Database.
> + //
> + Status = HiiDatabase->NewPackageList (
> + HiiDatabase,
> + PackageList,
> + NULL,
> + &mHiiHandle
> + );
> + if (!EFI_ERROR (Status)) {
> + Handle = NULL;
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &Handle,
> + &gEdkiiPlatformLogoProtocolGuid, &mPlatformLogo,
> + NULL
> + );
> + }
> + return Status;
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/PciLib.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/PciLib.c
> new file mode 100644
> index 0000000000..7544117a03
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/PciLib.c
> @@ -0,0 +1,1221 @@
> +/** @file
> + PCI Library functions that use
> + (a) I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles, layering
> + on top of one PCI CF8 Library instance; or
> + (b) PCI Library functions that use the 256 MB PCI Express MMIO window to
> + perform PCI Configuration cycles, layering on PCI Express Library.
> +
> + The decision is made in the entry point function, based on the OVMF platform
> + type, and then adhered to during the lifetime of the client module.
> +
> + Copyright (C) 2016, Red Hat, Inc.
> + Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include <Base.h>
> +
> +#include <IndustryStandard/X58Ich10.h>
> +
> +#include <Library/PciLib.h>
> +#include <Library/PciCf8Lib.h>
> +#include <Library/PciExpressLib.h>
> +#include <Library/PcdLib.h>
> +
> +STATIC BOOLEAN mRunningOnIch10;
> +
> +RETURN_STATUS
> +EFIAPI
> +InitializeConfigAccessMethod (
> + VOID
> + )
> +{
> + mRunningOnIch10 = (PcdGet16 (PcdSimicsX58HostBridgePciDevId) ==
> + INTEL_ICH10_DEVICE_ID);
> + return RETURN_SUCCESS;
> +}
> +
> +/**
> + Registers a PCI device so PCI configuration registers may be accessed after
> + SetVirtualAddressMap().
> +
> + Registers the PCI device specified by Address so all the PCI configuration
> registers
> + associated with that PCI device may be accessed after SetVirtualAddressMap()
> is called.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> +
> + @retval RETURN_SUCCESS The PCI device was registered for runtime
> access.
> + @retval RETURN_UNSUPPORTED An attempt was made to call this
> function
> + after ExitBootServices().
> + @retval RETURN_UNSUPPORTED The resources required to access the PCI
> device
> + at runtime could not be mapped.
> + @retval RETURN_OUT_OF_RESOURCES There are not enough resources
> available to
> + complete the registration.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +PciRegisterForRuntimeAccess (
> + IN UINTN Address
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressRegisterForRuntimeAccess (Address) :
> + PciCf8RegisterForRuntimeAccess (Address);
> +}
> +
> +/**
> + Reads an 8-bit PCI configuration register.
> +
> + Reads and returns the 8-bit PCI configuration register specified by Address.
> + This function must guarantee that all PCI read and write operations are
> + serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> +
> + @return The read value from the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciRead8 (
> + IN UINTN Address
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressRead8 (Address) :
> + PciCf8Read8 (Address);
> +}
> +
> +/**
> + Writes an 8-bit PCI configuration register.
> +
> + Writes the 8-bit PCI configuration register specified by Address with the
> + value specified by Value. Value is returned. This function must guarantee
> + that all PCI read and write operations are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param Value The value to write.
> +
> + @return The value written to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciWrite8 (
> + IN UINTN Address,
> + IN UINT8 Value
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressWrite8 (Address, Value) :
> + PciCf8Write8 (Address, Value);
> +}
> +
> +/**
> + Performs a bitwise OR of an 8-bit PCI configuration register with
> + an 8-bit value.
> +
> + Reads the 8-bit PCI configuration register specified by Address, performs a
> + bitwise OR between the read result and the value specified by
> + OrData, and writes the result to the 8-bit PCI configuration register
> + specified by Address. The value written to the PCI configuration register is
> + returned. This function must guarantee that all PCI read and write operations
> + are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param OrData The value to OR with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciOr8 (
> + IN UINTN Address,
> + IN UINT8 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressOr8 (Address, OrData) :
> + PciCf8Or8 (Address, OrData);
> +}
> +
> +/**
> + Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
> + value.
> +
> + Reads the 8-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData, and
> + writes the result to the 8-bit PCI configuration register specified by
> + Address. The value written to the PCI configuration register is returned.
> + This function must guarantee that all PCI read and write operations are
> + serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param AndData The value to AND with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciAnd8 (
> + IN UINTN Address,
> + IN UINT8 AndData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressAnd8 (Address, AndData) :
> + PciCf8And8 (Address, AndData);
> +}
> +
> +/**
> + Performs a bitwise AND of an 8-bit PCI configuration register with an 8-bit
> + value, followed a bitwise OR with another 8-bit value.
> +
> + Reads the 8-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData,
> + performs a bitwise OR between the result of the AND operation and
> + the value specified by OrData, and writes the result to the 8-bit PCI
> + configuration register specified by Address. The value written to the PCI
> + configuration register is returned. This function must guarantee that all PCI
> + read and write operations are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param AndData The value to AND with the PCI configuration register.
> + @param OrData The value to OR with the result of the AND operation.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciAndThenOr8 (
> + IN UINTN Address,
> + IN UINT8 AndData,
> + IN UINT8 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressAndThenOr8 (Address, AndData, OrData) :
> + PciCf8AndThenOr8 (Address, AndData, OrData);
> +}
> +
> +/**
> + Reads a bit field of a PCI configuration register.
> +
> + Reads the bit field in an 8-bit PCI configuration register. The bit field is
> + specified by the StartBit and the EndBit. The value of the bit field is
> + returned.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If StartBit is greater than 7, then ASSERT().
> + If EndBit is greater than 7, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> +
> + @param Address The PCI configuration register to read.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..7.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..7.
> +
> + @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciBitFieldRead8 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldRead8 (Address, StartBit, EndBit) :
> + PciCf8BitFieldRead8 (Address, StartBit, EndBit);
> +}
> +
> +/**
> + Writes a bit field to a PCI configuration register.
> +
> + Writes Value to the bit field of the PCI configuration register. The bit
> + field is specified by the StartBit and the EndBit. All other bits in the
> + destination PCI configuration register are preserved. The new value of the
> + 8-bit register is returned.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If StartBit is greater than 7, then ASSERT().
> + If EndBit is greater than 7, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If Value is larger than the bitmask value range specified by StartBit and EndBit,
> then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..7.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..7.
> + @param Value The new value of the bit field.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciBitFieldWrite8 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT8 Value
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldWrite8 (Address, StartBit, EndBit, Value) :
> + PciCf8BitFieldWrite8 (Address, StartBit, EndBit, Value);
> +}
> +
> +/**
> + Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
> + writes the result back to the bit field in the 8-bit port.
> +
> + Reads the 8-bit PCI configuration register specified by Address, performs a
> + bitwise OR between the read result and the value specified by
> + OrData, and writes the result to the 8-bit PCI configuration register
> + specified by Address. The value written to the PCI configuration register is
> + returned. This function must guarantee that all PCI read and write operations
> + are serialized. Extra left bits in OrData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If StartBit is greater than 7, then ASSERT().
> + If EndBit is greater than 7, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If OrData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..7.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..7.
> + @param OrData The value to OR with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciBitFieldOr8 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT8 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldOr8 (Address, StartBit, EndBit, OrData) :
> + PciCf8BitFieldOr8 (Address, StartBit, EndBit, OrData);
> +}
> +
> +/**
> + Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
> + AND, and writes the result back to the bit field in the 8-bit register.
> +
> + Reads the 8-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData, and
> + writes the result to the 8-bit PCI configuration register specified by
> + Address. The value written to the PCI configuration register is returned.
> + This function must guarantee that all PCI read and write operations are
> + serialized. Extra left bits in AndData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If StartBit is greater than 7, then ASSERT().
> + If EndBit is greater than 7, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If AndData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..7.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..7.
> + @param AndData The value to AND with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciBitFieldAnd8 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT8 AndData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldAnd8 (Address, StartBit, EndBit, AndData) :
> + PciCf8BitFieldAnd8 (Address, StartBit, EndBit, AndData);
> +}
> +
> +/**
> + Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
> + bitwise OR, and writes the result back to the bit field in the
> + 8-bit port.
> +
> + Reads the 8-bit PCI configuration register specified by Address, performs a
> + bitwise AND followed by a bitwise OR between the read result and
> + the value specified by AndData, and writes the result to the 8-bit PCI
> + configuration register specified by Address. The value written to the PCI
> + configuration register is returned. This function must guarantee that all PCI
> + read and write operations are serialized. Extra left bits in both AndData and
> + OrData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If StartBit is greater than 7, then ASSERT().
> + If EndBit is greater than 7, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If AndData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> + If OrData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..7.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..7.
> + @param AndData The value to AND with the PCI configuration register.
> + @param OrData The value to OR with the result of the AND operation.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT8
> +EFIAPI
> +PciBitFieldAndThenOr8 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT8 AndData,
> + IN UINT8 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData,
> OrData) :
> + PciCf8BitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData);
> +}
> +
> +/**
> + Reads a 16-bit PCI configuration register.
> +
> + Reads and returns the 16-bit PCI configuration register specified by Address.
> + This function must guarantee that all PCI read and write operations are
> + serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> +
> + @return The read value from the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciRead16 (
> + IN UINTN Address
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressRead16 (Address) :
> + PciCf8Read16 (Address);
> +}
> +
> +/**
> + Writes a 16-bit PCI configuration register.
> +
> + Writes the 16-bit PCI configuration register specified by Address with the
> + value specified by Value. Value is returned. This function must guarantee
> + that all PCI read and write operations are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param Value The value to write.
> +
> + @return The value written to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciWrite16 (
> + IN UINTN Address,
> + IN UINT16 Value
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressWrite16 (Address, Value) :
> + PciCf8Write16 (Address, Value);
> +}
> +
> +/**
> + Performs a bitwise OR of a 16-bit PCI configuration register with
> + a 16-bit value.
> +
> + Reads the 16-bit PCI configuration register specified by Address, performs a
> + bitwise OR between the read result and the value specified by
> + OrData, and writes the result to the 16-bit PCI configuration register
> + specified by Address. The value written to the PCI configuration register is
> + returned. This function must guarantee that all PCI read and write operations
> + are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param OrData The value to OR with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciOr16 (
> + IN UINTN Address,
> + IN UINT16 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressOr16 (Address, OrData) :
> + PciCf8Or16 (Address, OrData);
> +}
> +
> +/**
> + Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
> + value.
> +
> + Reads the 16-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData, and
> + writes the result to the 16-bit PCI configuration register specified by
> + Address. The value written to the PCI configuration register is returned.
> + This function must guarantee that all PCI read and write operations are
> + serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param AndData The value to AND with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciAnd16 (
> + IN UINTN Address,
> + IN UINT16 AndData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressAnd16 (Address, AndData) :
> + PciCf8And16 (Address, AndData);
> +}
> +
> +/**
> + Performs a bitwise AND of a 16-bit PCI configuration register with a 16-bit
> + value, followed a bitwise OR with another 16-bit value.
> +
> + Reads the 16-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData,
> + performs a bitwise OR between the result of the AND operation and
> + the value specified by OrData, and writes the result to the 16-bit PCI
> + configuration register specified by Address. The value written to the PCI
> + configuration register is returned. This function must guarantee that all PCI
> + read and write operations are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param AndData The value to AND with the PCI configuration register.
> + @param OrData The value to OR with the result of the AND operation.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciAndThenOr16 (
> + IN UINTN Address,
> + IN UINT16 AndData,
> + IN UINT16 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressAndThenOr16 (Address, AndData, OrData) :
> + PciCf8AndThenOr16 (Address, AndData, OrData);
> +}
> +
> +/**
> + Reads a bit field of a PCI configuration register.
> +
> + Reads the bit field in a 16-bit PCI configuration register. The bit field is
> + specified by the StartBit and the EndBit. The value of the bit field is
> + returned.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> + If StartBit is greater than 15, then ASSERT().
> + If EndBit is greater than 15, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> +
> + @param Address The PCI configuration register to read.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..15.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..15.
> +
> + @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciBitFieldRead16 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldRead16 (Address, StartBit, EndBit) :
> + PciCf8BitFieldRead16 (Address, StartBit, EndBit);
> +}
> +
> +/**
> + Writes a bit field to a PCI configuration register.
> +
> + Writes Value to the bit field of the PCI configuration register. The bit
> + field is specified by the StartBit and the EndBit. All other bits in the
> + destination PCI configuration register are preserved. The new value of the
> + 16-bit register is returned.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> + If StartBit is greater than 15, then ASSERT().
> + If EndBit is greater than 15, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If Value is larger than the bitmask value range specified by StartBit and EndBit,
> then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..15.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..15.
> + @param Value The new value of the bit field.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciBitFieldWrite16 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT16 Value
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldWrite16 (Address, StartBit, EndBit, Value) :
> + PciCf8BitFieldWrite16 (Address, StartBit, EndBit, Value);
> +}
> +
> +/**
> + Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
> + writes the result back to the bit field in the 16-bit port.
> +
> + Reads the 16-bit PCI configuration register specified by Address, performs a
> + bitwise OR between the read result and the value specified by
> + OrData, and writes the result to the 16-bit PCI configuration register
> + specified by Address. The value written to the PCI configuration register is
> + returned. This function must guarantee that all PCI read and write operations
> + are serialized. Extra left bits in OrData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> + If StartBit is greater than 15, then ASSERT().
> + If EndBit is greater than 15, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If OrData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..15.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..15.
> + @param OrData The value to OR with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciBitFieldOr16 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT16 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldOr16 (Address, StartBit, EndBit, OrData) :
> + PciCf8BitFieldOr16 (Address, StartBit, EndBit, OrData);
> +}
> +
> +/**
> + Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
> + AND, and writes the result back to the bit field in the 16-bit register.
> +
> + Reads the 16-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData, and
> + writes the result to the 16-bit PCI configuration register specified by
> + Address. The value written to the PCI configuration register is returned.
> + This function must guarantee that all PCI read and write operations are
> + serialized. Extra left bits in AndData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> + If StartBit is greater than 15, then ASSERT().
> + If EndBit is greater than 15, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If AndData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..15.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..15.
> + @param AndData The value to AND with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciBitFieldAnd16 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT16 AndData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldAnd16 (Address, StartBit, EndBit, AndData) :
> + PciCf8BitFieldAnd16 (Address, StartBit, EndBit, AndData);
> +}
> +
> +/**
> + Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
> + bitwise OR, and writes the result back to the bit field in the
> + 16-bit port.
> +
> + Reads the 16-bit PCI configuration register specified by Address, performs a
> + bitwise AND followed by a bitwise OR between the read result and
> + the value specified by AndData, and writes the result to the 16-bit PCI
> + configuration register specified by Address. The value written to the PCI
> + configuration register is returned. This function must guarantee that all PCI
> + read and write operations are serialized. Extra left bits in both AndData and
> + OrData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 16-bit boundary, then ASSERT().
> + If StartBit is greater than 15, then ASSERT().
> + If EndBit is greater than 15, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If AndData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> + If OrData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..15.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..15.
> + @param AndData The value to AND with the PCI configuration register.
> + @param OrData The value to OR with the result of the AND operation.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT16
> +EFIAPI
> +PciBitFieldAndThenOr16 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT16 AndData,
> + IN UINT16 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData,
> OrData) :
> + PciCf8BitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData);
> +}
> +
> +/**
> + Reads a 32-bit PCI configuration register.
> +
> + Reads and returns the 32-bit PCI configuration register specified by Address.
> + This function must guarantee that all PCI read and write operations are
> + serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> +
> + @return The read value from the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciRead32 (
> + IN UINTN Address
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressRead32 (Address) :
> + PciCf8Read32 (Address);
> +}
> +
> +/**
> + Writes a 32-bit PCI configuration register.
> +
> + Writes the 32-bit PCI configuration register specified by Address with the
> + value specified by Value. Value is returned. This function must guarantee
> + that all PCI read and write operations are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param Value The value to write.
> +
> + @return The value written to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciWrite32 (
> + IN UINTN Address,
> + IN UINT32 Value
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressWrite32 (Address, Value) :
> + PciCf8Write32 (Address, Value);
> +}
> +
> +/**
> + Performs a bitwise OR of a 32-bit PCI configuration register with
> + a 32-bit value.
> +
> + Reads the 32-bit PCI configuration register specified by Address, performs a
> + bitwise OR between the read result and the value specified by
> + OrData, and writes the result to the 32-bit PCI configuration register
> + specified by Address. The value written to the PCI configuration register is
> + returned. This function must guarantee that all PCI read and write operations
> + are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param OrData The value to OR with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciOr32 (
> + IN UINTN Address,
> + IN UINT32 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressOr32 (Address, OrData) :
> + PciCf8Or32 (Address, OrData);
> +}
> +
> +/**
> + Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
> + value.
> +
> + Reads the 32-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData, and
> + writes the result to the 32-bit PCI configuration register specified by
> + Address. The value written to the PCI configuration register is returned.
> + This function must guarantee that all PCI read and write operations are
> + serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param AndData The value to AND with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciAnd32 (
> + IN UINTN Address,
> + IN UINT32 AndData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressAnd32 (Address, AndData) :
> + PciCf8And32 (Address, AndData);
> +}
> +
> +/**
> + Performs a bitwise AND of a 32-bit PCI configuration register with a 32-bit
> + value, followed a bitwise OR with another 32-bit value.
> +
> + Reads the 32-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData,
> + performs a bitwise OR between the result of the AND operation and
> + the value specified by OrData, and writes the result to the 32-bit PCI
> + configuration register specified by Address. The value written to the PCI
> + configuration register is returned. This function must guarantee that all PCI
> + read and write operations are serialized.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> +
> + @param Address The address that encodes the PCI Bus, Device, Function and
> + Register.
> + @param AndData The value to AND with the PCI configuration register.
> + @param OrData The value to OR with the result of the AND operation.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciAndThenOr32 (
> + IN UINTN Address,
> + IN UINT32 AndData,
> + IN UINT32 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressAndThenOr32 (Address, AndData, OrData) :
> + PciCf8AndThenOr32 (Address, AndData, OrData);
> +}
> +
> +/**
> + Reads a bit field of a PCI configuration register.
> +
> + Reads the bit field in a 32-bit PCI configuration register. The bit field is
> + specified by the StartBit and the EndBit. The value of the bit field is
> + returned.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> + If StartBit is greater than 31, then ASSERT().
> + If EndBit is greater than 31, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> +
> + @param Address The PCI configuration register to read.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..31.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..31.
> +
> + @return The value of the bit field read from the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciBitFieldRead32 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldRead32 (Address, StartBit, EndBit) :
> + PciCf8BitFieldRead32 (Address, StartBit, EndBit);
> +}
> +
> +/**
> + Writes a bit field to a PCI configuration register.
> +
> + Writes Value to the bit field of the PCI configuration register. The bit
> + field is specified by the StartBit and the EndBit. All other bits in the
> + destination PCI configuration register are preserved. The new value of the
> + 32-bit register is returned.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> + If StartBit is greater than 31, then ASSERT().
> + If EndBit is greater than 31, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If Value is larger than the bitmask value range specified by StartBit and EndBit,
> then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..31.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..31.
> + @param Value The new value of the bit field.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciBitFieldWrite32 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT32 Value
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldWrite32 (Address, StartBit, EndBit, Value) :
> + PciCf8BitFieldWrite32 (Address, StartBit, EndBit, Value);
> +}
> +
> +/**
> + Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
> + writes the result back to the bit field in the 32-bit port.
> +
> + Reads the 32-bit PCI configuration register specified by Address, performs a
> + bitwise OR between the read result and the value specified by
> + OrData, and writes the result to the 32-bit PCI configuration register
> + specified by Address. The value written to the PCI configuration register is
> + returned. This function must guarantee that all PCI read and write operations
> + are serialized. Extra left bits in OrData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> + If StartBit is greater than 31, then ASSERT().
> + If EndBit is greater than 31, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If OrData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..31.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..31.
> + @param OrData The value to OR with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciBitFieldOr32 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT32 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldOr32 (Address, StartBit, EndBit, OrData) :
> + PciCf8BitFieldOr32 (Address, StartBit, EndBit, OrData);
> +}
> +
> +/**
> + Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
> + AND, and writes the result back to the bit field in the 32-bit register.
> +
> + Reads the 32-bit PCI configuration register specified by Address, performs a
> + bitwise AND between the read result and the value specified by AndData, and
> + writes the result to the 32-bit PCI configuration register specified by
> + Address. The value written to the PCI configuration register is returned.
> + This function must guarantee that all PCI read and write operations are
> + serialized. Extra left bits in AndData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> + If StartBit is greater than 31, then ASSERT().
> + If EndBit is greater than 31, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If AndData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..31.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..31.
> + @param AndData The value to AND with the PCI configuration register.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciBitFieldAnd32 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT32 AndData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldAnd32 (Address, StartBit, EndBit, AndData) :
> + PciCf8BitFieldAnd32 (Address, StartBit, EndBit, AndData);
> +}
> +
> +/**
> + Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
> + bitwise OR, and writes the result back to the bit field in the
> + 32-bit port.
> +
> + Reads the 32-bit PCI configuration register specified by Address, performs a
> + bitwise AND followed by a bitwise OR between the read result and
> + the value specified by AndData, and writes the result to the 32-bit PCI
> + configuration register specified by Address. The value written to the PCI
> + configuration register is returned. This function must guarantee that all PCI
> + read and write operations are serialized. Extra left bits in both AndData and
> + OrData are stripped.
> +
> + If Address > 0x0FFFFFFF, then ASSERT().
> + If Address is not aligned on a 32-bit boundary, then ASSERT().
> + If StartBit is greater than 31, then ASSERT().
> + If EndBit is greater than 31, then ASSERT().
> + If EndBit is less than StartBit, then ASSERT().
> + If AndData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> + If OrData is larger than the bitmask value range specified by StartBit and
> EndBit, then ASSERT().
> +
> + @param Address The PCI configuration register to write.
> + @param StartBit The ordinal of the least significant bit in the bit field.
> + Range 0..31.
> + @param EndBit The ordinal of the most significant bit in the bit field.
> + Range 0..31.
> + @param AndData The value to AND with the PCI configuration register.
> + @param OrData The value to OR with the result of the AND operation.
> +
> + @return The value written back to the PCI configuration register.
> +
> +**/
> +UINT32
> +EFIAPI
> +PciBitFieldAndThenOr32 (
> + IN UINTN Address,
> + IN UINTN StartBit,
> + IN UINTN EndBit,
> + IN UINT32 AndData,
> + IN UINT32 OrData
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData,
> OrData) :
> + PciCf8BitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData);
> +}
> +
> +/**
> + Reads a range of PCI configuration registers into a caller supplied buffer.
> +
> + Reads the range of PCI configuration registers specified by StartAddress and
> + Size into the buffer specified by Buffer. This function only allows the PCI
> + configuration registers from a single PCI function to be read. Size is
> + returned. When possible 32-bit PCI configuration read cycles are used to read
> + from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
> + and 16-bit PCI configuration read cycles may be used at the beginning and the
> + end of the range.
> +
> + If StartAddress > 0x0FFFFFFF, then ASSERT().
> + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> + If Size > 0 and Buffer is NULL, then ASSERT().
> +
> + @param StartAddress The starting address that encodes the PCI Bus, Device,
> + Function and Register.
> + @param Size The size in bytes of the transfer.
> + @param Buffer The pointer to a buffer receiving the data read.
> +
> + @return Size
> +
> +**/
> +UINTN
> +EFIAPI
> +PciReadBuffer (
> + IN UINTN StartAddress,
> + IN UINTN Size,
> + OUT VOID *Buffer
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressReadBuffer (StartAddress, Size, Buffer) :
> + PciCf8ReadBuffer (StartAddress, Size, Buffer);
> +}
> +
> +/**
> + Copies the data in a caller supplied buffer to a specified range of PCI
> + configuration space.
> +
> + Writes the range of PCI configuration registers specified by StartAddress and
> + Size from the buffer specified by Buffer. This function only allows the PCI
> + configuration registers from a single PCI function to be written. Size is
> + returned. When possible 32-bit PCI configuration write cycles are used to
> + write from StartAdress to StartAddress + Size. Due to alignment restrictions,
> + 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
> + and the end of the range.
> +
> + If StartAddress > 0x0FFFFFFF, then ASSERT().
> + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> + If Size > 0 and Buffer is NULL, then ASSERT().
> +
> + @param StartAddress The starting address that encodes the PCI Bus, Device,
> + Function and Register.
> + @param Size The size in bytes of the transfer.
> + @param Buffer The pointer to a buffer containing the data to write.
> +
> + @return Size written to StartAddress.
> +
> +**/
> +UINTN
> +EFIAPI
> +PciWriteBuffer (
> + IN UINTN StartAddress,
> + IN UINTN Size,
> + IN VOID *Buffer
> + )
> +{
> + return mRunningOnIch10 ?
> + PciExpressWriteBuffer (StartAddress, Size, Buffer) :
> + PciCf8WriteBuffer (StartAddress, Size, Buffer);
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.c
> new file mode 100644
> index 0000000000..b1d7552792
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.c
> @@ -0,0 +1,1579 @@
> +/** @file
> + ACPI Platform Driver
> +
> + Copyright (c) 2017 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_HEA
> DER *McfgTable;
> +
> EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_AD
> DRESS_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_BA
> SE_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_B
> ASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
> +
> EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVIS
> ION,
> + 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_HEA
> DER) +
> + sizeof
> (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_A
> DDRESS_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_B
> ASE_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/AcpiTa
> bles/Facs/Facs.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Facs/Facs.c
> new file mode 100644
> index 0000000000..a16c13466a
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/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) 2017 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/AcpiTa
> bles/Fadt/Fadt.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Fadt/Fadt.c
> new file mode 100644
> index 0000000000..8aa10a4a5b
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/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) 2017 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/AcpiTa
> bles/Hpet/Hpet.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Hpet/Hpet.c
> new file mode 100644
> index 0000000000..aa386ba149
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/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) 2017 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/AcpiTa
> bles/Wsmt/Wsmt.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Wsmt/Wsmt.c
> new file mode 100644
> index 0000000000..12e2feacb4
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/Wsmt/Wsmt.c
> @@ -0,0 +1,46 @@
> +/** @file
> + ACPI WSMT table
> +
> + Copyright (c) 2017 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/Co
> mponentName.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Co
> mponentName.c
> new file mode 100644
> index 0000000000..dd9cc80e42
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Co
> mponentName.c
> @@ -0,0 +1,205 @@
> +/** @file
> + Component name for the QEMU video controller.
> +
> + Copyright (c) 2006 - 2010, 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/Dri
> ver.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> ver.c
> new file mode 100644
> index 0000000000..e49e7a465c
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> ver.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/Dri
> verSupportedEfiVersion.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> verSupportedEfiVersion.c
> new file mode 100644
> index 0000000000..c2d82e7324
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dri
> verSupportedEfiVersion.c
> @@ -0,0 +1,15 @@
> +/** @file
> + Driver supported version protocol for the QEMU video driver.
> +
> + Copyright (c) 2007 - 2010 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/Go
> p.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Go
> p.c
> new file mode 100644
> index 0000000000..19ff5209d2
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Go
> p.c
> @@ -0,0 +1,417 @@
> +/** @file
> + Graphics Output Protocol functions for the QEMU video controller.
> +
> + Copyright (c) 2007 - 2018 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/Ini
> tialize.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Ini
> tialize.c
> new file mode 100644
> index 0000000000..fbf40e9eaf
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Ini
> tialize.c
> @@ -0,0 +1,341 @@
> +/** @file
> + Graphics Output Protocol functions for the QEMU video controller.
> +
> + Copyright (c) 2007 - 2010 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/Vb
> eShim.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.c
> new file mode 100644
> index 0000000000..aa4648f813
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.c
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.c
> new file mode 100644
> index 0000000000..b57bacdda4
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.c
> @@ -0,0 +1,622 @@
> +/** @file
> + This contains the installation function for the driver.
> +
> + Copyright (c) 2005 - 2018 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +**/
> +
> +#include "8259.h"
> +
> +//
> +// Global for the Legacy 8259 Protocol that is produced by this driver
> +//
> +EFI_LEGACY_8259_PROTOCOL mInterrupt8259 = {
> + Interrupt8259SetVectorBase,
> + Interrupt8259GetMask,
> + Interrupt8259SetMask,
> + Interrupt8259SetMode,
> + Interrupt8259GetVector,
> + Interrupt8259EnableIrq,
> + Interrupt8259DisableIrq,
> + Interrupt8259GetInterruptLine,
> + Interrupt8259EndOfInterrupt
> +};
> +
> +//
> +// Global for the handle that the Legacy 8259 Protocol is installed
> +//
> +EFI_HANDLE m8259Handle = NULL;
> +
> +UINT8 mMasterBase = 0xff;
> +UINT8 mSlaveBase = 0xff;
> +EFI_8259_MODE mMode = Efi8259ProtectedMode;
> +UINT16 mProtectedModeMask = 0xffff;
> +UINT16 mLegacyModeMask;
> +UINT16 mProtectedModeEdgeLevel = 0x0000;
> +UINT16 mLegacyModeEdgeLevel;
> +
> +//
> +// Worker Functions
> +//
> +
> +/**
> + Write to mask and edge/level triggered registers of master and slave 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));
> +}
> +
> +/**
> + Read from mask and edge/level triggered registers of master and slave PICs.
> +
> + @param[out] Mask low byte for master PIC mask register,
> + high byte for slave PIC mask register.
> + @param[out] EdgeLevel low byte for master PIC edge/level triggered
> register,
> + high byte for slave PIC edge/level triggered register.
> +
> +**/
> +VOID
> +Interrupt8259ReadMask (
> + OUT UINT16 *Mask,
> + OUT UINT16 *EdgeLevel
> + )
> +{
> + UINT16 MasterValue;
> + UINT16 SlaveValue;
> +
> + if (Mask != NULL) {
> + MasterValue = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
> + SlaveValue = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
> +
> + *Mask = (UINT16) (MasterValue | (SlaveValue << 8));
> + }
> +
> + if (EdgeLevel != NULL) {
> + MasterValue = IoRead8
> (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER);
> + SlaveValue = IoRead8
> (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE);
> +
> + *EdgeLevel = (UINT16) (MasterValue | (SlaveValue << 8));
> + }
> +}
> +
> +//
> +// Legacy 8259 Protocol Interface Functions
> +//
> +
> +/**
> + Sets the base address for the 8259 master and slave PICs.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
> + @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
> +
> + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> + @retval EFI_DEVICE_ERROR There was an error while writing to the 8259
> PIC.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259SetVectorBase (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT8 MasterBase,
> + IN UINT8 SlaveBase
> + )
> +{
> + UINT8 Mask;
> + EFI_TPL OriginalTpl;
> +
> + OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> + //
> + // Set vector base for slave PIC
> + //
> + if (SlaveBase != mSlaveBase) {
> + mSlaveBase = SlaveBase;
> +
> + //
> + // Initialization sequence is needed for setting vector base.
> + //
> +
> + //
> + // Preserve interrtup mask register before initialization sequence
> + // because it will be cleared during initialization
> + //
> + Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
> +
> + //
> + // ICW1: cascade mode, ICW4 write required
> + //
> + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, 0x11);
> +
> + //
> + // ICW2: new vector base (must be multiple of 8)
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, mSlaveBase);
> +
> + //
> + // ICW3: slave indentification code must be 2
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x02);
> +
> + //
> + // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x01);
> +
> + //
> + // Restore interrupt mask register
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, Mask);
> + }
> +
> + //
> + // Set vector base for master PIC
> + //
> + if (MasterBase != mMasterBase) {
> + mMasterBase = MasterBase;
> +
> + //
> + // Initialization sequence is needed for setting vector base.
> + //
> +
> + //
> + // Preserve interrtup mask register before initialization sequence
> + // because it will be cleared during initialization
> + //
> + Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
> +
> + //
> + // ICW1: cascade mode, ICW4 write required
> + //
> + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, 0x11);
> +
> + //
> + // ICW2: new vector base (must be multiple of 8)
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, mMasterBase);
> +
> + //
> + // ICW3: slave PIC is cascaded on IRQ2
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x04);
> +
> + //
> + // ICW4: fully nested mode, non-buffered mode, normal EOI, IA processor
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x01);
> +
> + //
> + // Restore interrupt mask register
> + //
> + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, Mask);
> + }
> +
> + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);
> + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER,
> LEGACY_8259_EOI);
> +
> + gBS->RestoreTPL (OriginalTpl);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> + @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
> + @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-
> IRQ15.
> + @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-
> IRQ15.
> + @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-
> IRQ15.
> +
> + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> + @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259GetMask (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + OUT UINT16 *LegacyMask, OPTIONAL
> + OUT UINT16 *LegacyEdgeLevel, OPTIONAL
> + OUT UINT16 *ProtectedMask, OPTIONAL
> + OUT UINT16 *ProtectedEdgeLevel OPTIONAL
> + )
> +{
> + if (LegacyMask != NULL) {
> + *LegacyMask = mLegacyModeMask;
> + }
> +
> + if (LegacyEdgeLevel != NULL) {
> + *LegacyEdgeLevel = mLegacyModeEdgeLevel;
> + }
> +
> + if (ProtectedMask != NULL) {
> + *ProtectedMask = mProtectedModeMask;
> + }
> +
> + if (ProtectedEdgeLevel != NULL) {
> + *ProtectedEdgeLevel = mProtectedModeEdgeLevel;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> + @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
> + @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
> + @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
> + @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-
> IRQ15.
> +
> + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> + @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259SetMask (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT16 *LegacyMask, OPTIONAL
> + IN UINT16 *LegacyEdgeLevel, OPTIONAL
> + IN UINT16 *ProtectedMask, OPTIONAL
> + IN UINT16 *ProtectedEdgeLevel OPTIONAL
> + )
> +{
> + if (LegacyMask != NULL) {
> + mLegacyModeMask = *LegacyMask;
> + }
> +
> + if (LegacyEdgeLevel != NULL) {
> + mLegacyModeEdgeLevel = *LegacyEdgeLevel;
> + }
> +
> + if (ProtectedMask != NULL) {
> + mProtectedModeMask = *ProtectedMask;
> + }
> +
> + if (ProtectedEdgeLevel != NULL) {
> + mProtectedModeEdgeLevel = *ProtectedEdgeLevel;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Sets the mode of the PICs.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Mode 16-bit real or 32-bit protected mode.
> + @param[in] Mask The value with which to set the interrupt mask.
> + @param[in] EdgeLevel The value with which to set the edge/level mask.
> +
> + @retval EFI_SUCCESS The mode was set successfully.
> + @retval EFI_INVALID_PARAMETER The mode was not set.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259SetMode (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_MODE Mode,
> + IN UINT16 *Mask, OPTIONAL
> + IN UINT16 *EdgeLevel OPTIONAL
> + )
> +{
> + if (Mode == mMode) {
> + return EFI_SUCCESS;
> + }
> +
> + if (Mode == Efi8259LegacyMode) {
> + //
> + // In Efi8259ProtectedMode, mask and edge/level trigger registers should
> + // be changed through this protocol, so we can track them in the
> + // corresponding module variables.
> + //
> + Interrupt8259ReadMask (&mProtectedModeMask,
> &mProtectedModeEdgeLevel);
> +
> + if (Mask != NULL) {
> + //
> + // Update the Mask for the new mode
> + //
> + mLegacyModeMask = *Mask;
> + }
> +
> + if (EdgeLevel != NULL) {
> + //
> + // Update the Edge/Level triggered mask for the new mode
> + //
> + mLegacyModeEdgeLevel = *EdgeLevel;
> + }
> +
> + mMode = Mode;
> +
> + //
> + // Write new legacy mode mask/trigger level
> + //
> + Interrupt8259WriteMask (mLegacyModeMask, mLegacyModeEdgeLevel);
> +
> + return EFI_SUCCESS;
> + }
> +
> + if (Mode == Efi8259ProtectedMode) {
> + //
> + // Save the legacy mode mask/trigger level
> + //
> + Interrupt8259ReadMask (&mLegacyModeMask, &mLegacyModeEdgeLevel);
> + //
> + // Always force Timer to be enabled after return from 16-bit code.
> + // This always insures that on next entry, timer is counting.
> + //
> + mLegacyModeMask &= 0xFFFE;
> +
> + if (Mask != NULL) {
> + //
> + // Update the Mask for the new mode
> + //
> + mProtectedModeMask = *Mask;
> + }
> +
> + if (EdgeLevel != NULL) {
> + //
> + // Update the Edge/Level triggered mask for the new mode
> + //
> + mProtectedModeEdgeLevel = *EdgeLevel;
> + }
> +
> + mMode = Mode;
> +
> + //
> + // Write new protected mode mask/trigger level
> + //
> + Interrupt8259WriteMask (mProtectedModeMask,
> mProtectedModeEdgeLevel);
> +
> + return EFI_SUCCESS;
> + }
> +
> + return EFI_INVALID_PARAMETER;
> +}
> +
> +/**
> + Translates the IRQ into a vector.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq IRQ0-IRQ15.
> + @param[out] Vector The vector that is assigned to the IRQ.
> +
> + @retval EFI_SUCCESS The Vector that matches Irq was returned.
> + @retval EFI_INVALID_PARAMETER Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259GetVector (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + OUT UINT8 *Vector
> + )
> +{
> + if ((UINT32)Irq > Efi8259Irq15) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (Irq <= Efi8259Irq7) {
> + *Vector = (UINT8) (mMasterBase + Irq);
> + } else {
> + *Vector = (UINT8) (mSlaveBase + (Irq - Efi8259Irq8));
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Enables the specified IRQ.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq IRQ0-IRQ15.
> + @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
> +
> + @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259EnableIrq (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + IN BOOLEAN LevelTriggered
> + )
> +{
> + if ((UINT32)Irq > Efi8259Irq15) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + mProtectedModeMask = (UINT16) (mProtectedModeMask & ~(1 << Irq));
> + if (LevelTriggered) {
> + mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel | (1 <<
> Irq));
> + } else {
> + mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1
> << Irq));
> + }
> +
> + Interrupt8259WriteMask (mProtectedModeMask,
> mProtectedModeEdgeLevel);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Disables the specified IRQ.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq IRQ0-IRQ15.
> +
> + @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259DisableIrq (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + )
> +{
> + if ((UINT32)Irq > Efi8259Irq15) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + mProtectedModeMask = (UINT16) (mProtectedModeMask | (1 << Irq));
> +
> + mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel & ~(1 <<
> Irq));
> +
> + Interrupt8259WriteMask (mProtectedModeMask,
> mProtectedModeEdgeLevel);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Reads the PCI configuration space to get the interrupt number that is assigned
> to the card.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] PciHandle PCI function for which to return the vector.
> + @param[out] Vector IRQ number that corresponds to the interrupt line.
> +
> + @retval EFI_SUCCESS The interrupt line value was read successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259GetInterruptLine (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_HANDLE PciHandle,
> + OUT UINT8 *Vector
> + )
> +{
> + EFI_PCI_IO_PROTOCOL *PciIo;
> + UINT8 InterruptLine;
> + EFI_STATUS Status;
> +
> + Status = gBS->HandleProtocol (
> + PciHandle,
> + &gEfiPciIoProtocolGuid,
> + (VOID **) &PciIo
> + );
> + if (EFI_ERROR (Status)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + PciIo->Pci.Read (
> + PciIo,
> + EfiPciIoWidthUint8,
> + PCI_INT_LINE_OFFSET,
> + 1,
> + &InterruptLine
> + );
> + //
> + // Interrupt line is same location for standard PCI cards, standard
> + // bridge and CardBus bridge.
> + //
> + *Vector = InterruptLine;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Issues the End of Interrupt (EOI) commands to PICs.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq The interrupt for which to issue the EOI command.
> +
> + @retval EFI_SUCCESS The EOI command was issued.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259EndOfInterrupt (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + )
> +{
> + if ((UINT32)Irq > Efi8259Irq15) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (Irq >= Efi8259Irq8) {
> + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, LEGACY_8259_EOI);
> + }
> +
> + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER,
> LEGACY_8259_EOI);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Driver Entry point.
> +
> + @param[in] ImageHandle ImageHandle of the loaded driver.
> + @param[in] SystemTable Pointer to the EFI System Table.
> +
> + @retval EFI_SUCCESS One or more of the drivers returned a success code.
> + @retval !EFI_SUCCESS Error installing Legacy 8259 Protocol.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Install8259 (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> + EFI_8259_IRQ Irq;
> +
> + //
> + // Initialze mask values from PCDs
> + //
> + mLegacyModeMask = PcdGet16 (Pcd8259LegacyModeMask);
> + mLegacyModeEdgeLevel = PcdGet16 (Pcd8259LegacyModeEdgeLevel);
> +
> + //
> + // Clear all pending interrupt
> + //
> + for (Irq = Efi8259Irq0; Irq <= Efi8259Irq15; Irq++) {
> + Interrupt8259EndOfInterrupt (&mInterrupt8259, Irq);
> + }
> +
> + //
> + // Set the 8259 Master base to 0x68 and the 8259 Slave base to 0x70
> + //
> + Status = Interrupt8259SetVectorBase (&mInterrupt8259,
> PROTECTED_MODE_BASE_VECTOR_MASTER,
> PROTECTED_MODE_BASE_VECTOR_SLAVE);
> +
> + //
> + // Set all 8259 interrupts to edge triggered and disabled
> + //
> + Interrupt8259WriteMask (mProtectedModeMask,
> mProtectedModeEdgeLevel);
> +
> + //
> + // Install 8259 Protocol onto a new handle
> + //
> + Status = gBS->InstallProtocolInterface (
> + &m8259Handle,
> + &gEfiLegacy8259ProtocolGuid,
> + EFI_NATIVE_INTERFACE,
> + &mInterrupt8259
> + );
> + return Status;
> +}
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridge.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridge.h
> new file mode 100644
> index 0000000000..3bf31067fa
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridge.h
> @@ -0,0 +1,68 @@
> +/** @file
> + Header file of OVMF instance of PciHostBridgeLib.
> +
> + Copyright (c) 2016 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/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.inf
> new file mode 100644
> index 0000000000..8c6de3dca6
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/PciH
> ostBridgeLib/PciHostBridgeLib.inf
> @@ -0,0 +1,50 @@
> +## @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/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> + BaseMemoryLib
> + DebugLib
> + DevicePathLib
> + MemoryAllocationLib
> + PciLib
> +
> +[Pcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase
> + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base
> + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.h
> new file mode 100644
> index 0000000000..1fb031b752
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/BdsPlatform.h
> @@ -0,0 +1,156 @@
> +/** @file
> + Platform BDS customizations include file.
> +
> + Copyright (c) 2006 - 2017 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
> + );
> +
> +#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformBootManagerLib.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformBootManagerLib.inf
> new file mode 100644
> index 0000000000..55da35e87d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Platf
> ormBootManagerLib/PlatformBootManagerLib.inf
> @@ -0,0 +1,69 @@
> +## @file
> +# Platform BDS customizations library.
> +#
> +# Copyright (c) 2007 - 2018 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/SimicsOpenBoardPkg.dec
> + OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + MemoryAllocationLib
> + UefiBootServicesTableLib
> + BaseMemoryLib
> + DebugLib
> + PcdLib
> + UefiBootManagerLib
> + BootLogoLib
> + DevicePathLib
> + PciLib
> + NvVarsFileLib
> + LoadLinuxLib
> + UefiLib
> +
> +[Pcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent
> + gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
> + gSimicsX58PkgTokenSpaceGuid.PcdShellFile
> +
> +[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/Overrides/MdeModulePkg/Logo/Logo.b
> mp
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.b
> mp
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..86d7030833a096f54539
> 3735d931d9f4f2fbf8c0
> 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@*`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+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&BD
> W#
> 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`MbpMs
> Hs!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{s
> 5Us
> 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&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+^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&
> 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}x
> H
> 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@R
> yE}
> 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_XLhaJH
> k9y
> 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#>@h
> Ag0B
> 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+iW
> LO
> 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#;pb9MET
> 3i
> 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^)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*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>_
> pcCU
> zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?cu
> n1%}
> 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~0iLGTxcoR
> PfI4bJ
> 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_^>{+voM4X
> f6<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=&|)SoC
> VC
> 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;op
> qN
> 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?tOz
> z;Fg
> z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSItN
> x
> 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@pcE
> zabu
> 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_v
> 8
> 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;PC7
> PV
> zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^N
> 8-|
> 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>nILXnDZc
> l-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{EARWbyDMH
> hU<^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?NDG
> SQXu
> 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#cQu
> pq
> 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}QPZIah
> 0x
> 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>zMY
> J#!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;1
> y
> 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%ah7VBO
> Y4
> z(Y$TKzJ<J=gNJ^gBA_sfu}}9Z=354HEKK*k*S!&$B(%S5KF_V06KimjU+smdwE?G
> g
> 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~|*N
> yv3
> 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?7t0Oo3
> y|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+0EXJc
> p@|
> 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!Et3gM
> Lk
> TuM~Ktz$*n_Dey{xHWc`O(cS1K
>
> literal 0
> HcmV?d00001
>
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.id
> f
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> df
> new file mode 100644
> index 0000000000..1f79332020
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> df
> @@ -0,0 +1,10 @@
> +// /** @file
> +// Platform Logo image definition file.
> +//
> +// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +#image IMG_LOGO Logo.bmp
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.in
> f
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> nf
> new file mode 100644
> index 0000000000..3380f3c1d5
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> nf
> @@ -0,0 +1,28 @@
> +## @file
> +# The default logo bitmap picture shown on setup screen, which is
> corresponding to gEfiDefaultBmpLogoGuid.
> +#
> +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = Logo
> + MODULE_UNI_FILE = Logo.uni
> + FILE_GUID = 7BB28B99-61BB-11D5-9A5D-0090273FC14D
> + 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 ARM AARCH64
> +#
> +
> +[Binaries]
> + BIN|Logo.bmp|*
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> + LogoExtra.uni
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.u
> ni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.u
> ni
> new file mode 100644
> index 0000000000..9d1bbaffa9
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.u
> ni
> @@ -0,0 +1,16 @@
> +// /** @file
> +// The default logo bitmap picture shown on setup screen, which is
> corresponding to gEfiDefaultBmpLogoGuid.
> +//
> +// This module provides the default logo bitmap picture shown on setup
> screen, which corresponds to gEfiDefaultBmpLogoGuid.
> +//
> +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT #language en-US "Provides the default
> logo bitmap picture shown on setup screen, which corresponds to
> gEfiDefaultBmpLogoGuid"
> +
> +#string STR_MODULE_DESCRIPTION #language en-US "This module
> provides the default logo bitmap picture shown on setup screen, which
> corresponds to gEfiDefaultBmpLogoGuid."
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.inf
> new file mode 100644
> index 0000000000..01102b138f
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.inf
> @@ -0,0 +1,55 @@
> +## @file
> +# The default logo bitmap picture shown on setup screen.
> +#
> +# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = LogoDxe
> + MODULE_UNI_FILE = LogoDxe.uni
> + FILE_GUID = F74D20EE-37E7-48FC-97F7-9B1047749C69
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> +
> + ENTRY_POINT = InitializeLogo
> +#
> +# This flag specifies whether HII resource section is generated into PE image.
> +#
> + UEFI_HII_RESOURCE_SECTION = TRUE
> +
> +#
> +# The following information is for reference only and not required by the build
> tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Sources]
> + Logo.bmp
> + Logo.c
> + Logo.idf
> +
> +[Packages]
> + MdeModulePkg/MdeModulePkg.dec
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + UefiBootServicesTableLib
> + UefiDriverEntryPoint
> + DebugLib
> +
> +[Protocols]
> + gEfiHiiDatabaseProtocolGuid ## CONSUMES
> + gEfiHiiImageExProtocolGuid ## CONSUMES
> + gEfiHiiPackageListProtocolGuid ## PRODUCES CONSUMES
> + gEdkiiPlatformLogoProtocolGuid ## PRODUCES
> +
> +[Depex]
> + gEfiHiiDatabaseProtocolGuid AND
> + gEfiHiiImageExProtocolGuid
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> + LogoDxeExtra.uni
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.uni
> new file mode 100644
> index 0000000000..9635701b60
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.uni
> @@ -0,0 +1,16 @@
> +// /** @file
> +// The default logo bitmap picture shown on setup screen.
> +//
> +// This module provides the default logo bitmap picture shown on setup
> screen, through EDKII Platform Logo protocol.
> +//
> +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT #language en-US "Provides the default
> logo bitmap picture shown on setup screen."
> +
> +#string STR_MODULE_DESCRIPTION #language en-US "This module
> provides the default logo bitmap picture shown on setup screen, through EDKII
> Platform Logo protocol."
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xeExtra.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xeExtra.uni
> new file mode 100644
> index 0000000000..c6ea34b81d
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xeExtra.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +// Logo Localized Strings and Content
> +//
> +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +#string STR_PROPERTIES_MODULE_NAME
> +#language en-US
> +"Logo Image File"
> +
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoEx
> tra.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoEx
> tra.uni
> new file mode 100644
> index 0000000000..041179fb75
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoEx
> tra.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +// Logo Localized Strings and Content
> +//
> +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +#string STR_PROPERTIES_MODULE_NAME
> +#language en-US
> +"Logo Image File"
> +
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/DxePciLibX58Ich10.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/DxePciLibX58Ich10.inf
> new file mode 100644
> index 0000000000..e5ca95e20e
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibCf
> 8/DxePciLibX58Ich10.inf
> @@ -0,0 +1,40 @@
> +## @file
> +# An instance of the PCI Library that is based on both the PCI CF8 Library and
> +# the PCI Express Library.
> +#
> +# This PciLib instance caches the SimicsX58 platform type (X58-ICH10) in
> +# its entry point function, then delegates function calls to one of the
> +# PciCf8Lib or PciExpressLib "backends" as appropriate.
> +#
> +# Copyright (C) 2016, Red Hat, Inc.
> +# Copyright (c) 2007 - 2014 Intel Corporation. All rights reserved. <BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = DxePciLibX58Ich10
> + FILE_GUID = FC214B5D-B5B5-4E54-9B28-5E94532E5E2A
> + MODULE_TYPE = BASE
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = PciLib|DXE_DRIVER DXE_RUNTIME_DRIVER
> SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION
> + CONSTRUCTOR = InitializeConfigAccessMethod
> +
> +# VALID_ARCHITECTURES = IA32 X64
> +
> +[Sources]
> + PciLib.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> + PcdLib
> + PciCf8Lib
> + PciExpressLib
> +
> +[Pcd]
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.h
> new file mode 100644
> index 0000000000..2deb2a88eb
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.h
> @@ -0,0 +1,45 @@
> +/** @file
> + This is an implementation of the ACPI platform driver.
> +
> + Copyright (c) 2017 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/AcpiTa
> bles/AcpiPlatform.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.inf
> new file mode 100644
> index 0000000000..b4b52b6622
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiTa
> bles/AcpiPlatform.inf
> @@ -0,0 +1,105 @@
> +## @file
> +# Component information file for AcpiPlatform module
> +#
> +# Copyright (c) 2017 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/Qe
> mu.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> mu.h
> new file mode 100644
> index 0000000000..f6ef44a14f
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> mu.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/Qe
> muVideoDxe.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> muVideoDxe.inf
> new file mode 100644
> index 0000000000..8370559016
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Qe
> muVideoDxe.inf
> @@ -0,0 +1,73 @@
> +## @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/SimicsOpenBoardPkg.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
> + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> + gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.asm
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.asm
> new file mode 100644
> index 0000000000..cb2a60d827
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.asm
> @@ -0,0 +1,281 @@
> +;------------------------------------------------------------------------------
> +; @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/Vb
> eShim.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.h
> new file mode 100644
> index 0000000000..cc9b6e14cd
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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/Vb
> eShim.sh
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.sh
> new file mode 100644
> index 0000000000..7669f8a219
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Vb
> eShim.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
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.h
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.h
> new file mode 100644
> index 0000000000..a9673f9c87
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.h
> @@ -0,0 +1,218 @@
> +/** @file
> + Driver implementing the Tiano Legacy 8259 Protocol
> +
> +Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef _8259_H__
> +#define _8259_H__
> +
> +#include <Protocol/Legacy8259.h>
> +#include <Protocol/PciIo.h>
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +
> +#include <IndustryStandard/Pci.h>
> +
> +// 8259 Hardware definitions
> +
> +#define LEGACY_MODE_BASE_VECTOR_MASTER 0x08
> +#define LEGACY_MODE_BASE_VECTOR_SLAVE 0x70
> +
> +#define PROTECTED_MODE_BASE_VECTOR_MASTER 0x68
> +#define PROTECTED_MODE_BASE_VECTOR_SLAVE 0x70
> +
> +#define LEGACY_8259_CONTROL_REGISTER_MASTER 0x20
> +#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
> +#define LEGACY_8259_CONTROL_REGISTER_SLAVE 0xA0
> +#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
> +
> +#define LEGACY_8259_EOI 0x20
> +
> +// Protocol Function Prototypes
> +
> +/**
> + Sets the base address for the 8259 master and slave PICs.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
> + @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
> +
> + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> + @retval EFI_DEVICE_ERROR There was an error while writing to the 8259
> PIC.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259SetVectorBase (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT8 MasterBase,
> + IN UINT8 SlaveBase
> + );
> +
> +/**
> + Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> + @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
> + @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-
> IRQ15.
> + @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-
> IRQ15.
> + @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-
> IRQ15.
> +
> + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> + @retval EFI_DEVICE_ERROR There was an error while reading the 8259 PIC.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259GetMask (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + OUT UINT16 *LegacyMask, OPTIONAL
> + OUT UINT16 *LegacyEdgeLevel, OPTIONAL
> + OUT UINT16 *ProtectedMask, OPTIONAL
> + OUT UINT16 *ProtectedEdgeLevel OPTIONAL
> + );
> +
> +/**
> + Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> + @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-IRQ15.
> + @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-IRQ15.
> + @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-IRQ15.
> + @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-
> IRQ15.
> +
> + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> + @retval EFI_DEVICE_ERROR There was an error while writing the 8259 PIC.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259SetMask (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN UINT16 *LegacyMask, OPTIONAL
> + IN UINT16 *LegacyEdgeLevel, OPTIONAL
> + IN UINT16 *ProtectedMask, OPTIONAL
> + IN UINT16 *ProtectedEdgeLevel OPTIONAL
> + );
> +
> +/**
> + Sets the mode of the PICs.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Mode 16-bit real or 32-bit protected mode.
> + @param[in] Mask The value with which to set the interrupt mask.
> + @param[in] EdgeLevel The value with which to set the edge/level mask.
> +
> + @retval EFI_SUCCESS The mode was set successfully.
> + @retval EFI_INVALID_PARAMETER The mode was not set.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259SetMode (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_MODE Mode,
> + IN UINT16 *Mask, OPTIONAL
> + IN UINT16 *EdgeLevel OPTIONAL
> + );
> +
> +/**
> + Translates the IRQ into a vector.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq IRQ0-IRQ15.
> + @param[out] Vector The vector that is assigned to the IRQ.
> +
> + @retval EFI_SUCCESS The Vector that matches Irq was returned.
> + @retval EFI_INVALID_PARAMETER Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259GetVector (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + OUT UINT8 *Vector
> + );
> +
> +/**
> + Enables the specified IRQ.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq IRQ0-IRQ15.
> + @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
> +
> + @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259EnableIrq (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq,
> + IN BOOLEAN LevelTriggered
> + );
> +
> +/**
> + Disables the specified IRQ.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq IRQ0-IRQ15.
> +
> + @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259DisableIrq (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + );
> +
> +/**
> + Reads the PCI configuration space to get the interrupt number that is assigned
> to the card.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] PciHandle PCI function for which to return the vector.
> + @param[out] Vector IRQ number that corresponds to the interrupt line.
> +
> + @retval EFI_SUCCESS The interrupt line value was read successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259GetInterruptLine (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_HANDLE PciHandle,
> + OUT UINT8 *Vector
> + );
> +
> +/**
> + Issues the End of Interrupt (EOI) commands to PICs.
> +
> + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> + @param[in] Irq The interrupt for which to issue the EOI command.
> +
> + @retval EFI_SUCCESS The EOI command was issued.
> + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +Interrupt8259EndOfInterrupt (
> + IN EFI_LEGACY_8259_PROTOCOL *This,
> + IN EFI_8259_IRQ Irq
> + );
> +
> +#endif
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.inf
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.inf
> new file mode 100644
> index 0000000000..e66b21c914
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/8259.inf
> @@ -0,0 +1,46 @@
> +## @file
> +# 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
> +#
> +# Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = Legacy8259
> + MODULE_UNI_FILE = Legacy8259.uni
> + FILE_GUID = 79CA4208-BBA1-4a9a-8456-E1E66A81484E
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = Install8259
> +
> +[Sources]
> + 8259.c
> + 8259.h
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + PcAtChipsetPkg/PcAtChipsetPkg.dec
> + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> +
> +[LibraryClasses]
> + UefiBootServicesTableLib
> + DebugLib
> + UefiDriverEntryPoint
> + IoLib
> + PcdLib
> +
> +[Protocols]
> + gEfiLegacy8259ProtocolGuid ## PRODUCES
> + gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMES
> +
> +[Pcd]
> + gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask ##
> CONSUMES
> + gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel ##
> CONSUMES
> +
> +[Depex]
> + TRUE
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> + Legacy8259Extra.uni
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259.uni
> new file mode 100644
> index 0000000000..d035292419
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259.uni
> @@ -0,0 +1,16 @@
> +// /** @file
> +// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
> +//
> +// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
> +//
> +// Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT #language en-US "8259 Interrupt
> Controller driver that provides Legacy 8259 protocol"
> +
> +#string STR_MODULE_DESCRIPTION #language en-US "8259 Interrupt
> Controller driver that provides Legacy 8259 protocol."
> +
> diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259Extra.uni
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259Extra.uni
> new file mode 100644
> index 0000000000..ee43f6923c
> --- /dev/null
> +++
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> ptControllerDxe/Legacy8259Extra.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +// Legacy8259 Localized Strings and Content
> +//
> +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +#string STR_PROPERTIES_MODULE_NAME
> +#language en-US
> +"Legacy 8259 Interrupt Controller DXE Driver"
> +
> +
> --
> 2.16.2.windows.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58
2019-08-22 22:31 ` David Wei
@ 2019-08-26 22:48 ` Kubacki, Michael A
0 siblings, 0 replies; 37+ messages in thread
From: Kubacki, Michael A @ 2019-08-26 22:48 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Thanks David. No more comments for this patch.
> -----Original Message-----
> From: Wei, David Y
> Sent: Thursday, August 22, 2019 3:31 PM
> To: Kubacki, Michael A <michael.a.kubacki@intel.com>; 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>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for
> SimicsX58
>
> Hi Mike,
> Please see the updates online below. Please let me know if you have any more
> comments.
>
> Thanks
> David
>
> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Monday, August 19, 2019 6:04 PM
> To: Wei, David Y <david.y.wei@intel.com>; 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>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for
> SimicsX58
>
> Feedback I could not find already noted elsewhere:
>
> 1. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c:
> There's some style issues throughout the file related to a missing space
> before opening parenthesis and parameters than span multiple lines.
> Some of these are pre-existing in OvmfPkg source. I don't think this is a
> must have.
> Ydwei: done
> 2. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 265:
> "Confirm if QEMU supports SMRAM." to "Confirm if Simics supports
> SMRAM."
> Ydwei: done
> 3. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 275:
> "DEBUG((EFI_D_ERROR, "TopOfLowRam =0x%x; TopOfLowRamMb =0x%x
> \n", TopOfLowRam, TopOfLowRamMb));"
> Should be an informational message.
> Ydwei: done
> 3. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 283:
> "DEBUG((EFI_D_ERROR, "MCH_TOLUD =0x%x; \n",
> PciRead32(DRAMC_REGISTER_X58(MCH_TOLUD))));"
> Should be an informational message.
> Ydwei: done
> 4. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c - Line 300 &
> Line 301 - Should be informational messages as well.
> Ydwei: done
> 5. Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf: Is a
> dependency on OvmfPkg/OvmfPkg.dec required? This dependency should be
> avoided.
> Ydwei: done
> 6. Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore: I don't think
> this should be an override but should exist in a similar manner
> as edk2/OvmfPkg/Sec. The code cannot be upstreamed as-is.
> Ydwei: done
> 7. /Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c:
> Some of this messages should probably be verbose not informational.
> Ydwei: done
> 8. /Silicon/Intel/SimicsX58SktPkg/SktPei.dsc: This file naming convention is
> unusual. SktPkgPei.dsc is more consistent.
> Ydwei: done
> > -----Original Message-----
> > From: Wei, David Y
> > Sent: Friday, August 9, 2019 3:47 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-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for
> > SimicsX58
> >
> > 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>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> >
> > Signed-off-by: David Wei <david.y.wei@intel.com>
> > ---
> > .../Override/UefiCpuPkg/SecCore/SecMain.c | 956
> > +++++++++++++++++++++
> > .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.c | 148 ++++
> > .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.c | 353 ++++++++
> > .../SimicsX58SktPkg/Smm/Access/SmramInternal.c | 199 +++++
> > .../Override/UefiCpuPkg/SecCore/Ia32/SecEntry.nasm | 45 +
> > .../Override/UefiCpuPkg/SecCore/SecMain.inf | 71 ++
> > .../Override/UefiCpuPkg/SecCore/X64/SecEntry.nasm | 45 +
> > Silicon/Intel/SimicsX58SktPkg/SktPei.dsc | 18 +
> > .../Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf | 9 +
> > .../Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf | 10 +
> > Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf | 17 +
> > .../Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf | 16 +
> > .../SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf | 52 ++
> > .../SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf | 64 ++
> > .../SimicsX58SktPkg/Smm/Access/SmramInternal.h | 81 ++
> > 15 files changed, 2084 insertions(+)
> > create mode 100644
> > Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.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
> >
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry.n
> as
> > m
> > create mode 100644
> > Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> > create mode 100644
> >
> Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.n
> as
> > m
> > create mode 100644 Silicon/Intel/SimicsX58SktPkg/SktPei.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/Override/UefiCpuPkg/SecCore/SecMain.c
> > b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.c
> > new file mode 100644
> > index 0000000000..c52d459ef2
> > --- /dev/null
> > +++
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/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 <IndustryStandard/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_INFO, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "PcdSimicsDxeMemFvBase: 0x%x\n", PcdGet32
> > (PcdSimicsDxeMemFvBase)));
> > + DEBUG ((EFI_D_INFO, "OutputBuffer: 0x%x\n", OutputBuffer));
> > + DEBUG ((EFI_D_INFO, "OutputBufferSize: 0x%x\n", OutputBufferSize));
> > + DEBUG ((EFI_D_INFO, "ScratchBuffer: 0x%x\n", ScratchBuffer));
> > + DEBUG ((EFI_D_INFO, "ScratchBufferSize: 0x%x\n", ScratchBufferSize));
> > + DEBUG ((EFI_D_INFO, "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_ERROR, "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_INFO, "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_INFO, "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_INFO, "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_INFO, "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/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..d07d88142a
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.c
> > @@ -0,0 +1,353 @@
> > +/** @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, 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 <SimicsPlatforms.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 QEMU 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 QEMU.
> > + //
> > +
> > + TopOfLowRam = GetSystemMemorySizeBelow4gb ();
> > + ASSERT ((TopOfLowRam & (SIZE_1MB - 1)) == 0);
> > + TopOfLowRamMb = TopOfLowRam >> 20;
> > + DEBUG((EFI_D_ERROR, "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_ERROR, "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_ERROR, "MCH_TSEGMB =0x%x; \n",
> > PciRead32(DRAMC_REGISTER_X58(MCH_TSEGMB))));
> > + DEBUG((EFI_D_ERROR, "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..898fc25084
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmramInternal.c
> > @@ -0,0 +1,199 @@
> > +/** @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 <Guid/AcpiS3Context.h>
> > +#include <IndustryStandard/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/Override/UefiCpuPkg/SecCore/Ia32/SecEntry
> .n
> > asm
> >
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry
> .
> > nasm
> > new file mode 100644
> > index 0000000000..19ffb6f86d
> > --- /dev/null
> > +++
> >
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/Ia32/SecEntry
> .
> > nasm
> > @@ -0,0 +1,45 @@
> > +; @file
> > +; Copyright (c) 2006 - 2013 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/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> > b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> > new file mode 100644
> > index 0000000000..ac993ac1ce
> > --- /dev/null
> > +++
> > b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/SecMain.inf
> > @@ -0,0 +1,71 @@
> > +## @file
> > +# SEC Driver
> > +#
> > +# Copyright (c) 2008 - 2018 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
> > + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> > +
> > +[LibraryClasses]
> > + BaseLib
> > + DebugLib
> > + BaseMemoryLib
> > + PeiServicesLib
> > + PcdLib
> > + UefiCpuLib
> > + DebugAgentLib
> > + IoLib
> > + PeCoffLib
> > + PeCoffGetEntryPointLib
> > + PeCoffExtraActionLib
> > + ExtractGuidedSectionLib
> > + LocalApicLib
> > + PciCf8Lib
> > +
> > +[Ppis]
> > + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
> > +
> > +[Pcd]
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> > + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> > + gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> > +
> > +[FeaturePcd]
> > + gSimicsX58PkgTokenSpaceGuid.PcdSmmSmramRequire
> > diff --git
> >
> a/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.
> n
> > asm
> >
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.
> n
> > asm
> > new file mode 100644
> > index 0000000000..0eb86ec2ca
> > --- /dev/null
> > +++
> >
> b/Silicon/Intel/SimicsX58SktPkg/Override/UefiCpuPkg/SecCore/X64/SecEntry.
> n
> > asm
> > @@ -0,0 +1,45 @@
> > +; @file
> > +; Copyright (c) 2006 - 2013 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/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> > b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> > new file mode 100644
> > index 0000000000..0be8be4966
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/SktPei.dsc
> > @@ -0,0 +1,18 @@
> > +## @file
> > +# Component description file for the SkyLake SiPkg PEI drivers.
> > +#
> > +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > + #
> > + # SEC Phase modules
> > + #
> > + $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf {
> > + <LibraryClasses>
> > +
> >
> NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDeco
> m
> > pressLib.inf
> > + }
> > + 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..78eca21a43
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/SktPostMemoryInclude.fdf
> > @@ -0,0 +1,9 @@
> > +## @file
> > +# Component description file for the SkyLake SiPkg DXE drivers.
> > +#
> > +# Copyright (c) 2017 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..9f037e99d4
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/SktPreMemoryInclude.fdf
> > @@ -0,0 +1,10 @@
> > +## @file
> > +# Component description file for the SkyLake SiPkg PEI drivers.
> > +#
> > +# Copyright (c) 2017 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..596d633cd3
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/SktSecInclude.fdf
> > @@ -0,0 +1,17 @@
> > +## @file
> > +# Component description file for the SkyLake SiPkg PEI drivers.
> > +#
> > +# Copyright (c) 2017 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_SECMAIN USE = IA32
> > $(SKT_PKG)/Override/UefiCpuPkg/SecCore/SecMain.inf
> > +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..9004b9cb83
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/SktUefiBootInclude.fdf
> > @@ -0,0 +1,16 @@
> > +## @file
> > +# Component description file for the SkyLake SiPkg DXE drivers.
> > +#
> > +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +#INF
> $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuArchDxe/CpuArchDxe.inf
> > +#INF $(SKT_PKG)/Override/IA32FamilyCpuPkg/CpuMpDxe/CpuMpDxe.inf
> > +!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..2f630b4b95
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccess2Dxe.inf
> > @@ -0,0 +1,52 @@
> > +## @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.
> > +#
> > +# 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
> > + SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..1d3b028c85
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsX58SktPkg/Smm/Access/SmmAccessPei.inf
> > @@ -0,0 +1,64 @@
> > +## @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.
> > +#
> > +# 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
> > + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> > + OvmfPkg/OvmfPkg.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 [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10
2019-08-23 16:40 ` David Wei
@ 2019-08-26 22:49 ` Kubacki, Michael A
0 siblings, 0 replies; 37+ messages in thread
From: Kubacki, Michael A @ 2019-08-26 22:49 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Thanks David. No more comments for this patch.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 23, 2019 9:40 AM
> To: Kubacki, Michael A <michael.a.kubacki@intel.com>; 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>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for
> SimicsICH10
>
> Hi Mike,
> Please see the updates online below. Please let me know if you have any more
> comments.
>
> Thanks
> David
>
> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Monday, August 19, 2019 6:04 PM
> To: Wei, David Y <david.y.wei@intel.com>; 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>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for
> SimicsICH10
>
> Feedback I could not find already noted elsewhere:
>
> 1.
> /Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePc
> hSpiCommonLib.inf:
> This silicon package should not have a dependency on MinPlatformPkg.dec.
> Ydwei: done
> 2.
> /Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePc
> hSpiCommonLib.inf:
> This silicon package should not have a dependency on
> SimicsOpenBoardPkg.dec.
> Ydwei: done
> 3. Although noted elsewhere: I also prefer Pascal naming as well so
> SimicsIch10Pkg.
> Ydwei: done
> 4. /Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.c:
> "Reset System Library functions for OVMF" - replace OVMF with Simics
> ICH10.
> Ydwei: done
> 5. /Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.inf:
> This silicon package INF should not have a dependency on
> MinPlatformPkg.dec.
> Ydwei: done
> 6.
> /Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.inf
> This silicon package INF should not have a dependency on
> MinPlatformPkg.dec.
> Ydwei: done
> 7.
> /Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonib/SmmSpiFlash
> CommonLib:
> This silicon package INF should not have a dependency on
> MinPlatformPkg.dec.
> Ydwei: done
> > -----Original Message-----
> > From: Wei, David Y
> > Sent: Friday, August 9, 2019 3:47 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-platform patch 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>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> >
> > 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 | 22 +
> > .../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 +++++++
> > .../IncludePrivate/Library/PchSpiCommonLib.h | 396 +++++++++
> > .../Library/ResetSystemLib/ResetSystemLib.inf | 34 +
> > .../SmmSpiFlashCommonLib/SmmSpiFlashCommonLib.inf | 52 ++
> > .../BasePchSpiCommonLib/BasePchSpiCommonLib.inf | 33 +
> > Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc | 12 +
> > .../Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf | 9 +
> > .../Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf | 9 +
> > .../Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf | 13 +
> > .../SmmControl/RuntimeDxe/SmmControl2Dxe.inf | 59 ++
> > Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpi.h | 23 +
> > Silicon/Intel/SimicsICH10Pkg/Spi/Smm/PchSpiSmm.inf | 44 +
> > 25 files changed, 4152 insertions(+)
> > create mode 100644
> > Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.c
> > create mode 100644
> >
> Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCom
> mo
> > n.c
> > create mode 100644
> >
> Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCom
> mo
> > nSmmLib.c
> > create mode 100644
> >
> Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCom
> mo
> > n.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/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/IncludePrivate/Library/PchSpiCommonLib.h
> > create mode 100644
> > Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.inf
> > create mode 100644
> >
> Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlash
> Co
> > mmonLib.inf
> > create mode 100644
> >
> Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePch
> Spi
> > CommonLib.inf
> > create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
> > create mode 100644
> Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
> > create mode 100644
> Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
> > create mode 100644 Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
> > 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..46355e191c
> > --- /dev/null
> > +++
> b/Silicon/Intel/SimicsICH10Pkg/Library/ResetSystemLib/ResetSystemLib.c
> > @@ -0,0 +1,137 @@
> > +/** @file
> > + Reset System Library functions for OVMF
> > +
> > + Copyright (c) 2006 - 2016 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 <IndustryStandard/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/SpiFlashCo
> m
> > mon.c
> >
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCo
> m
> > mon.c
> > new file mode 100644
> > index 0000000000..3d4e24eac6
> > --- /dev/null
> > +++
> >
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCo
> m
> > mon.c
> > @@ -0,0 +1,194 @@
> > +/** @file
> > + Wrap EFI_SPI_PROTOCOL to provide some library level interfaces
> > + for module use.
> > +
> > + Copyright (c) 2017 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/SpiFlashCo
> m
> > monSmmLib.c
> >
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCo
> m
> > monSmmLib.c
> > new file mode 100644
> > index 0000000000..1e5cd0d744
> > --- /dev/null
> > +++
> >
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SpiFlashCo
> m
> > monSmmLib.c
> > @@ -0,0 +1,54 @@
> > +/** @file
> > + SMM Library instance of SPI Flash Common Library Class
> > +
> > + Copyright (c) 2017 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/SpiCo
> m
> > mon.c
> >
> b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCo
> m
> > mon.c
> > new file mode 100644
> > index 0000000000..77fb76d7cd
> > --- /dev/null
> > +++
> >
> b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/SpiCo
> m
> > mon.c
> > @@ -0,0 +1,935 @@
> > +/** @file
> > + PCH SPI Common Driver implements the SPI Host Controller Compatibility
> > Interface.
> > +
> > + Copyright (c) 2017 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 <IndustryStandard/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..8fb4947b1a
> > --- /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 - 2010, Intel Corporation. All rights reserved.<BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include <IndustryStandard/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..19eb469657
> > --- /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) 2017 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..f9d340d6df
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsICH10Pkg/ICH10Pkg.dec
> > @@ -0,0 +1,22 @@
> > +## @file
> > +# Copyright (c) 2014 - 2016 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}}
> > diff --git
> a/Silicon/Intel/SimicsICH10Pkg/Include/Library/SpiFlashCommonLib.h
> > b/Silicon/Intel/SimicsICH10Pkg/Include/Library/SpiFlashCommonLib.h
> > new file mode 100644
> > index 0000000000..c36360bcb0
> > --- /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) 2017 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..552ce28d8c
> > --- /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) 2017 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..d503d130c8
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsICH10Pkg/Include/PchLimits.h
> > @@ -0,0 +1,94 @@
> > +/** @file
> > + Build time limits of PCH resources.
> > +
> > + Copyright (c) 2017 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..00139fc230
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsICH10Pkg/Include/PchReservedResources.h
> > @@ -0,0 +1,60 @@
> > +/** @file
> > + PCH preserved MMIO resource definitions.
> > +
> > + Copyright (c) 2017 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..cb5f26c47b
> > --- /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) 2017 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..e08721f405
> > --- /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) 2017 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..a727aae927
> > --- /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) 2017 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/IncludePrivate/Library/PchSpiCommonLib.h
> > b/Silicon/Intel/SimicsICH10Pkg/IncludePrivate/Library/PchSpiCommonLib.h
> > new file mode 100644
> > index 0000000000..5bdec96197
> > --- /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) 2017 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..4af462da47
> > --- /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 - 2018 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
> > + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> > +
> > +[LibraryClasses]
> > + DebugLib
> > + IoLib
> > + TimerLib
> > diff --git
> >
> a/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFlas
> h
> > CommonLib.inf
> >
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFla
> sh
> > CommonLib.inf
> > new file mode 100644
> > index 0000000000..b5c97f1930
> > --- /dev/null
> > +++
> >
> b/Silicon/Intel/SimicsICH10Pkg/Library/SmmSpiFlashCommonLib/SmmSpiFla
> sh
> > CommonLib.inf
> > @@ -0,0 +1,52 @@
> > +## @file
> > +# SMM Library instance of Spi Flash Common Library Class
> > +#
> > +# Copyright (c) 2017 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
> > + MinPlatformPkg/MinPlatformPkg.dec
> > +
> > +
> > +[Pcd]
> > + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ##
> CONSUMES
> > + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
> > +
> > +[Sources]
> > + SpiFlashCommonSmmLib.c
> > + SpiFlashCommon.c
> > +
> > +[Protocols]
> > + gEfiSmmSpiProtocolGuid ## CONSUMES
> > +
> > +[Depex.X64.DXE_SMM_DRIVER]
> > + gEfiSmmSpiProtocolGuid
> > diff --git
> >
> a/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BasePc
> h
> > SpiCommonLib.inf
> >
> b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BaseP
> ch
> > SpiCommonLib.inf
> > new file mode 100644
> > index 0000000000..11c832e487
> > --- /dev/null
> > +++
> >
> b/Silicon/Intel/SimicsICH10Pkg/LibraryPrivate/BasePchSpiCommonLib/BaseP
> ch
> > SpiCommonLib.inf
> > @@ -0,0 +1,33 @@
> > +## @file
> > +# Component description file for the PchSpiCommonLib
> > +#
> > +# Copyright (c) 2017 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
> > + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> > + MinPlatformPkg/MinPlatformPkg.dec
> > +
> > +[LibraryClasses]
> > + IoLib
> > + DebugLib
> > +
> > +[Pcd]
> > + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ##
> CONSUMES
> > + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## CONSUMES
> > diff --git a/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
> > b/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
> > new file mode 100644
> > index 0000000000..a2d006ee35
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsICH10Pkg/PchCommonLib.dsc
> > @@ -0,0 +1,12 @@
> > +## @file
> > +# Component description file for the SkyLake SiPkg DXE libraries.
> > +#
> > +# Copyright (c) 2017 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/BaseP
> c
> > hSpiCommonLib.inf
> > diff --git a/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
> > b/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
> > new file mode 100644
> > index 0000000000..78eca21a43
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsICH10Pkg/PchPostMemoryInclude.fdf
> > @@ -0,0 +1,9 @@
> > +## @file
> > +# Component description file for the SkyLake SiPkg DXE drivers.
> > +#
> > +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > diff --git a/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
> > b/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
> > new file mode 100644
> > index 0000000000..2d3a127c20
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsICH10Pkg/PchPreMemoryInclude.fdf
> > @@ -0,0 +1,9 @@
> > +## @file
> > +# Component description file for the SkyLake SiPkg PEI drivers.
> > +#
> > +# Copyright (c) 2017 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > diff --git a/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
> > b/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
> > new file mode 100644
> > index 0000000000..d079c593d9
> > --- /dev/null
> > +++ b/Silicon/Intel/SimicsICH10Pkg/PchUefiBootInclude.fdf
> > @@ -0,0 +1,13 @@
> > +## @file
> > +# Component description file for the SkyLake SiPkg DXE drivers.
> > +#
> > +# Copyright (c) 2017 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/SmmControl/RuntimeDxe/SmmControl2Dxe.i
> nf
> >
> b/Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.i
> nf
> > new file mode 100644
> > index 0000000000..e23dd9f2fe
> > --- /dev/null
> > +++
> >
> b/Silicon/Intel/SimicsICH10Pkg/SmmControl/RuntimeDxe/SmmControl2Dxe.i
> nf
> > @@ -0,0 +1,59 @@
> > +## @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.
> > +#
> > +# 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
> > + SimicsOpenBoardPkg/SimicsOpenBoardPkg.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..f7fdd3abbe
> > --- /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) 2017 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..265af00ac0
> > --- /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) 2017 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 [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform
2019-08-23 17:09 ` David Wei
@ 2019-08-26 22:51 ` Kubacki, Michael A
0 siblings, 0 replies; 37+ messages in thread
From: Kubacki, Michael A @ 2019-08-26 22:51 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Thanks David. No more comments for this patch.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 23, 2019 10:10 AM
> To: Kubacki, Michael A <michael.a.kubacki@intel.com>;
> 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>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides
> modules for SIMICS QSP Platform
>
> Hi Mike,
> Please see the updates online below. Please let me know if you have any
> more comments.
>
> Thanks
> David
>
> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Monday, August 19, 2019 6:05 PM
> To: Wei, David Y <david.y.wei@intel.com>; 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>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides
> modules for SIMICS QSP Platform
>
> Agree with Nate's feedback on moving the noted items out of the
> "Overrides" directory.
> Ydwei: done
> Please do submit a patch for style fixes in MinPlatformPkg/Acpi/AcpiTables
> directly.
>
> > -----Original Message-----
> > From: Wei, David Y
> > Sent: Friday, August 9, 2019 3:47 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-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides
> > modules for SIMICS QSP Platform
> >
> > Overrides/MdeModulePkg/Library/PciHostBridgeLib - it is platform related.
> > should be Customized
> > Overrides/MdeModulePkg/Logo - the Logo image is Customized
> > Overrides/MdePkg/Library/BasePciLibCf8 - use the functions specific for
> SIMICS
> >
> > 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>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> >
> > Signed-off-by: David Wei <david.y.wei@intel.com>
> > ---
> > .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 419 ++++++
> > .../Library/PlatformBootManagerLib/BdsPlatform.c | 1553
> > +++++++++++++++++++
> > .../Library/PlatformBootManagerLib/PlatformData.c | 35 +
> > .../Overrides/MdeModulePkg/Logo/Logo.c | 154 ++
> > .../MdePkg/Library/BasePciLibCf8/PciLib.c | 1221 +++++++++++++++
> > .../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 | 417 ++++++
> > .../Overrides/OvmfPkg/QemuVideoDxe/Initialize.c | 341 +++++
> > .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.c | 302 ++++
> > .../8259InterruptControllerDxe/8259.c | 622 ++++++++
> > .../Library/PciHostBridgeLib/PciHostBridge.h | 68 +
> > .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 50 +
> > .../Library/PlatformBootManagerLib/BdsPlatform.h | 156 ++
> > .../PlatformBootManagerLib.inf | 69 +
> > .../Overrides/MdeModulePkg/Logo/Logo.bmp | Bin 0 -> 141078
> bytes
> > .../Overrides/MdeModulePkg/Logo/Logo.idf | 10 +
> > .../Overrides/MdeModulePkg/Logo/Logo.inf | 28 +
> > .../Overrides/MdeModulePkg/Logo/Logo.uni | 16 +
> > .../Overrides/MdeModulePkg/Logo/LogoDxe.inf | 55 +
> > .../Overrides/MdeModulePkg/Logo/LogoDxe.uni | 16 +
> > .../Overrides/MdeModulePkg/Logo/LogoDxeExtra.uni | 14 +
> > .../Overrides/MdeModulePkg/Logo/LogoExtra.uni | 14 +
> > .../Library/BasePciLibCf8/DxePciLibX58Ich10.inf | 40 +
> > .../MinPlatformPkg/Acpi/AcpiTables/AcpiPlatform.h | 45 +
> > .../Acpi/AcpiTables/AcpiPlatform.inf | 105 ++
> > .../Overrides/OvmfPkg/QemuVideoDxe/Qemu.h | 507 +++++++
> > .../OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf | 73 +
> > .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.asm | 281 ++++
> > .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.h | 701 +++++++++
> > .../Overrides/OvmfPkg/QemuVideoDxe/VbeShim.sh | 79 +
> > .../8259InterruptControllerDxe/8259.h | 218 +++
> > .../8259InterruptControllerDxe/8259.inf | 46 +
> > .../8259InterruptControllerDxe/Legacy8259.uni | 16 +
> > .../8259InterruptControllerDxe/Legacy8259Extra.uni | 14 +
> > 41 files changed, 11062 insertions(+)
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pci
> Hos
> > tBridgeLib/PciHostBridgeLib.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Plat
> for
> > mBootManagerLib/BdsPlatform.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Plat
> for
> > mBootManagerLib/PlatformData.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.
> c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibC
> f8/
> > PciLib.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/AcpiPlatform.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/Facs/Facs.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/Fadt/Fadt.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/Hpet/Hpet.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/Wsmt/Wsmt.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/C
> om
> > ponentName.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dr
> iv
> > er.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Dr
> iv
> > erSupportedEfiVersion.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/G
> op.
> > c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Ini
> tia
> > lize.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
> beS
> > him.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> pt
> > ControllerDxe/8259.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pci
> Hos
> > tBridgeLib/PciHostBridge.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pci
> Hos
> > tBridgeLib/PciHostBridgeLib.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Plat
> for
> > mBootManagerLib/BdsPlatform.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Plat
> for
> > mBootManagerLib/PlatformBootManagerLib.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.
> bm
> > p
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> df
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.i
> nf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Logo.
> uni
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.
> > inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe.
> > uni
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoD
> xe
> > Extra.uni
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/LogoE
> xtr
> > a.uni
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLibC
> f8/
> > DxePciLibX58Ich10.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/AcpiPlatform.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/AcpiT
> abl
> > es/AcpiPlatform.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Q
> em
> > u.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/Q
> em
> > uVideoDxe.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
> beS
> > him.asm
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
> beS
> > him.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/V
> beS
> > him.sh
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> pt
> > ControllerDxe/8259.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> pt
> > ControllerDxe/8259.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> pt
> > ControllerDxe/Legacy8259.uni
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interru
> pt
> > ControllerDxe/Legacy8259Extra.uni
> >
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridgeLib.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridgeLib.c
> > new file mode 100644
> > index 0000000000..2aaa4b3e90
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridgeLib.c
> > @@ -0,0 +1,419 @@
> > +/** @file
> > + OVMF'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 <IndustryStandard/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_PREFETCHABL
> E
> > + ) != 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/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/BdsPlatform.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/BdsPlatform.c
> > new file mode 100644
> > index 0000000000..0b66862e46
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/BdsPlatform.c
> > @@ -0,0 +1,1553 @@
> > +/** @file
> > + Platform BDS customizations.
> > +
> > + Copyright (c) 2004 - 2018 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
> > + //
> > + BootLogoEnableLogo();
> > +
> > + 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/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/PlatformData.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/PlatformData.c
> > new file mode 100644
> > index 0000000000..5f1b16dd56
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/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 - 2017 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/Overrides/MdeModulePkg/Logo/Log
> o.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.c
> > new file mode 100644
> > index 0000000000..d4a75ad140
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.c
> > @@ -0,0 +1,154 @@
> > +/** @file
> > + Logo DXE Driver, install Edkii Platform Logo protocol.
> > +
> > + Copyright (c) 2016 - 2017 Intel Corporation. All rights reserved. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <Protocol/HiiDatabase.h>
> > +#include <Protocol/GraphicsOutput.h>
> > +#include <Protocol/HiiImageEx.h>
> > +#include <Protocol/PlatformLogo.h>
> > +#include <Protocol/HiiPackageList.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/DebugLib.h>
> > +
> > +typedef struct {
> > + EFI_IMAGE_ID ImageId;
> > + EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE Attribute;
> > + INTN OffsetX;
> > + INTN OffsetY;
> > +} LOGO_ENTRY;
> > +
> > +EFI_HII_IMAGE_EX_PROTOCOL *mHiiImageEx;
> > +EFI_HII_HANDLE mHiiHandle;
> > +LOGO_ENTRY mLogos[] = {
> > + {
> > + IMAGE_TOKEN (IMG_LOGO),
> > + EdkiiPlatformLogoDisplayAttributeCenter,
> > + 0,
> > + 0
> > + }
> > +};
> > +
> > +/**
> > + Load a platform logo image and return its data and attributes.
> > +
> > + @param This The pointer to this protocol instance.
> > + @param Instance The visible image instance is found.
> > + @param Image Points to the image.
> > + @param Attribute The display attributes of the image returned.
> > + @param OffsetX The X offset of the image regarding the Attribute.
> > + @param OffsetY The Y offset of the image regarding the Attribute.
> > +
> > + @retval EFI_SUCCESS The image was fetched successfully.
> > + @retval EFI_NOT_FOUND The specified image could not be found.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetImage (
> > + IN EDKII_PLATFORM_LOGO_PROTOCOL *This,
> > + IN OUT UINT32 *Instance,
> > + OUT EFI_IMAGE_INPUT *Image,
> > + OUT EDKII_PLATFORM_LOGO_DISPLAY_ATTRIBUTE *Attribute,
> > + OUT INTN *OffsetX,
> > + OUT INTN *OffsetY
> > + )
> > +{
> > + UINT32 Current;
> > + if (Instance == NULL || Image == NULL ||
> > + Attribute == NULL || OffsetX == NULL || OffsetY == NULL) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + Current = *Instance;
> > + if (Current >= ARRAY_SIZE (mLogos)) {
> > + return EFI_NOT_FOUND;
> > + }
> > +
> > + (*Instance)++;
> > + *Attribute = mLogos[Current].Attribute;
> > + *OffsetX = mLogos[Current].OffsetX;
> > + *OffsetY = mLogos[Current].OffsetY;
> > + return mHiiImageEx->GetImageEx (mHiiImageEx, mHiiHandle,
> > mLogos[Current].ImageId, Image);
> > +}
> > +
> > +EDKII_PLATFORM_LOGO_PROTOCOL mPlatformLogo = {
> > + GetImage
> > +};
> > +
> > +/**
> > + Entrypoint of this module.
> > +
> > + This function is the entrypoint of this module. It installs the Edkii
> > + Platform Logo protocol.
> > +
> > + @param ImageHandle The firmware allocated handle for the EFI
> image.
> > + @param SystemTable A pointer to the EFI System Table.
> > +
> > + @retval EFI_SUCCESS The entry point is executed successfully.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +InitializeLogo (
> > + IN EFI_HANDLE ImageHandle,
> > + IN EFI_SYSTEM_TABLE *SystemTable
> > + )
> > +{
> > + EFI_STATUS Status;
> > + EFI_HII_PACKAGE_LIST_HEADER *PackageList;
> > + EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
> > + EFI_HANDLE Handle;
> > +
> > + Status = gBS->LocateProtocol (
> > + &gEfiHiiDatabaseProtocolGuid,
> > + NULL,
> > + (VOID **) &HiiDatabase
> > + );
> > + ASSERT_EFI_ERROR (Status);
> > +
> > + Status = gBS->LocateProtocol (
> > + &gEfiHiiImageExProtocolGuid,
> > + NULL,
> > + (VOID **) &mHiiImageEx
> > + );
> > + ASSERT_EFI_ERROR (Status);
> > +
> > + //
> > + // Retrieve HII package list from ImageHandle
> > + //
> > + Status = gBS->OpenProtocol (
> > + ImageHandle,
> > + &gEfiHiiPackageListProtocolGuid,
> > + (VOID **) &PackageList,
> > + ImageHandle,
> > + NULL,
> > + EFI_OPEN_PROTOCOL_GET_PROTOCOL
> > + );
> > + if (EFI_ERROR (Status)) {
> > + DEBUG ((DEBUG_ERROR, "HII Image Package with logo not found in
> > PE/COFF resource section\n"));
> > + return Status;
> > + }
> > +
> > + //
> > + // Publish HII package list to HII Database.
> > + //
> > + Status = HiiDatabase->NewPackageList (
> > + HiiDatabase,
> > + PackageList,
> > + NULL,
> > + &mHiiHandle
> > + );
> > + if (!EFI_ERROR (Status)) {
> > + Handle = NULL;
> > + Status = gBS->InstallMultipleProtocolInterfaces (
> > + &Handle,
> > + &gEdkiiPlatformLogoProtocolGuid, &mPlatformLogo,
> > + NULL
> > + );
> > + }
> > + return Status;
> > +}
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLi
> bCf
> > 8/PciLib.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLi
> bCf
> > 8/PciLib.c
> > new file mode 100644
> > index 0000000000..7544117a03
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLi
> bCf
> > 8/PciLib.c
> > @@ -0,0 +1,1221 @@
> > +/** @file
> > + PCI Library functions that use
> > + (a) I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles,
> layering
> > + on top of one PCI CF8 Library instance; or
> > + (b) PCI Library functions that use the 256 MB PCI Express MMIO window
> to
> > + perform PCI Configuration cycles, layering on PCI Express Library.
> > +
> > + The decision is made in the entry point function, based on the OVMF
> platform
> > + type, and then adhered to during the lifetime of the client module.
> > +
> > + Copyright (C) 2016, Red Hat, Inc.
> > + Copyright (c) 2006 - 2012 Intel Corporation. All rights reserved. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include <Base.h>
> > +
> > +#include <IndustryStandard/X58Ich10.h>
> > +
> > +#include <Library/PciLib.h>
> > +#include <Library/PciCf8Lib.h>
> > +#include <Library/PciExpressLib.h>
> > +#include <Library/PcdLib.h>
> > +
> > +STATIC BOOLEAN mRunningOnIch10;
> > +
> > +RETURN_STATUS
> > +EFIAPI
> > +InitializeConfigAccessMethod (
> > + VOID
> > + )
> > +{
> > + mRunningOnIch10 = (PcdGet16 (PcdSimicsX58HostBridgePciDevId) ==
> > + INTEL_ICH10_DEVICE_ID);
> > + return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> > + Registers a PCI device so PCI configuration registers may be accessed
> after
> > + SetVirtualAddressMap().
> > +
> > + Registers the PCI device specified by Address so all the PCI configuration
> > registers
> > + associated with that PCI device may be accessed after
> SetVirtualAddressMap()
> > is called.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > +
> > + @retval RETURN_SUCCESS The PCI device was registered for
> runtime
> > access.
> > + @retval RETURN_UNSUPPORTED An attempt was made to call this
> > function
> > + after ExitBootServices().
> > + @retval RETURN_UNSUPPORTED The resources required to access
> the PCI
> > device
> > + at runtime could not be mapped.
> > + @retval RETURN_OUT_OF_RESOURCES There are not enough resources
> > available to
> > + complete the registration.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +PciRegisterForRuntimeAccess (
> > + IN UINTN Address
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressRegisterForRuntimeAccess (Address) :
> > + PciCf8RegisterForRuntimeAccess (Address);
> > +}
> > +
> > +/**
> > + Reads an 8-bit PCI configuration register.
> > +
> > + Reads and returns the 8-bit PCI configuration register specified by
> Address.
> > + This function must guarantee that all PCI read and write operations are
> > + serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > +
> > + @return The read value from the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciRead8 (
> > + IN UINTN Address
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressRead8 (Address) :
> > + PciCf8Read8 (Address);
> > +}
> > +
> > +/**
> > + Writes an 8-bit PCI configuration register.
> > +
> > + Writes the 8-bit PCI configuration register specified by Address with the
> > + value specified by Value. Value is returned. This function must
> guarantee
> > + that all PCI read and write operations are serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > + @param Value The value to write.
> > +
> > + @return The value written to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciWrite8 (
> > + IN UINTN Address,
> > + IN UINT8 Value
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressWrite8 (Address, Value) :
> > + PciCf8Write8 (Address, Value);
> > +}
> > +
> > +/**
> > + Performs a bitwise OR of an 8-bit PCI configuration register with
> > + an 8-bit value.
> > +
> > + Reads the 8-bit PCI configuration register specified by Address, performs
> a
> > + bitwise OR between the read result and the value specified by
> > + OrData, and writes the result to the 8-bit PCI configuration register
> > + specified by Address. The value written to the PCI configuration register
> is
> > + returned. This function must guarantee that all PCI read and write
> operations
> > + are serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > + @param OrData The value to OR with the PCI configuration register.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciOr8 (
> > + IN UINTN Address,
> > + IN UINT8 OrData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressOr8 (Address, OrData) :
> > + PciCf8Or8 (Address, OrData);
> > +}
> > +
> > +/**
> > + Performs a bitwise AND of an 8-bit PCI configuration register with an 8-
> bit
> > + value.
> > +
> > + Reads the 8-bit PCI configuration register specified by Address, performs
> a
> > + bitwise AND between the read result and the value specified by
> AndData, and
> > + writes the result to the 8-bit PCI configuration register specified by
> > + Address. The value written to the PCI configuration register is returned.
> > + This function must guarantee that all PCI read and write operations are
> > + serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > + @param AndData The value to AND with the PCI configuration register.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciAnd8 (
> > + IN UINTN Address,
> > + IN UINT8 AndData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressAnd8 (Address, AndData) :
> > + PciCf8And8 (Address, AndData);
> > +}
> > +
> > +/**
> > + Performs a bitwise AND of an 8-bit PCI configuration register with an 8-
> bit
> > + value, followed a bitwise OR with another 8-bit value.
> > +
> > + Reads the 8-bit PCI configuration register specified by Address, performs
> a
> > + bitwise AND between the read result and the value specified by
> AndData,
> > + performs a bitwise OR between the result of the AND operation and
> > + the value specified by OrData, and writes the result to the 8-bit PCI
> > + configuration register specified by Address. The value written to the PCI
> > + configuration register is returned. This function must guarantee that all
> PCI
> > + read and write operations are serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > + @param AndData The value to AND with the PCI configuration register.
> > + @param OrData The value to OR with the result of the AND operation.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciAndThenOr8 (
> > + IN UINTN Address,
> > + IN UINT8 AndData,
> > + IN UINT8 OrData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressAndThenOr8 (Address, AndData, OrData) :
> > + PciCf8AndThenOr8 (Address, AndData, OrData);
> > +}
> > +
> > +/**
> > + Reads a bit field of a PCI configuration register.
> > +
> > + Reads the bit field in an 8-bit PCI configuration register. The bit field is
> > + specified by the StartBit and the EndBit. The value of the bit field is
> > + returned.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If StartBit is greater than 7, then ASSERT().
> > + If EndBit is greater than 7, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > +
> > + @param Address The PCI configuration register to read.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..7.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..7.
> > +
> > + @return The value of the bit field read from the PCI configuration
> register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciBitFieldRead8 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldRead8 (Address, StartBit, EndBit) :
> > + PciCf8BitFieldRead8 (Address, StartBit, EndBit);
> > +}
> > +
> > +/**
> > + Writes a bit field to a PCI configuration register.
> > +
> > + Writes Value to the bit field of the PCI configuration register. The bit
> > + field is specified by the StartBit and the EndBit. All other bits in the
> > + destination PCI configuration register are preserved. The new value of
> the
> > + 8-bit register is returned.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If StartBit is greater than 7, then ASSERT().
> > + If EndBit is greater than 7, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > + If Value is larger than the bitmask value range specified by StartBit and
> EndBit,
> > then ASSERT().
> > +
> > + @param Address The PCI configuration register to write.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..7.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..7.
> > + @param Value The new value of the bit field.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciBitFieldWrite8 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit,
> > + IN UINT8 Value
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldWrite8 (Address, StartBit, EndBit, Value) :
> > + PciCf8BitFieldWrite8 (Address, StartBit, EndBit, Value);
> > +}
> > +
> > +/**
> > + Reads a bit field in an 8-bit PCI configuration, performs a bitwise OR, and
> > + writes the result back to the bit field in the 8-bit port.
> > +
> > + Reads the 8-bit PCI configuration register specified by Address, performs
> a
> > + bitwise OR between the read result and the value specified by
> > + OrData, and writes the result to the 8-bit PCI configuration register
> > + specified by Address. The value written to the PCI configuration register
> is
> > + returned. This function must guarantee that all PCI read and write
> operations
> > + are serialized. Extra left bits in OrData are stripped.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If StartBit is greater than 7, then ASSERT().
> > + If EndBit is greater than 7, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > + If OrData is larger than the bitmask value range specified by StartBit and
> > EndBit, then ASSERT().
> > +
> > + @param Address The PCI configuration register to write.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..7.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..7.
> > + @param OrData The value to OR with the PCI configuration register.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciBitFieldOr8 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit,
> > + IN UINT8 OrData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldOr8 (Address, StartBit, EndBit, OrData) :
> > + PciCf8BitFieldOr8 (Address, StartBit, EndBit, OrData);
> > +}
> > +
> > +/**
> > + Reads a bit field in an 8-bit PCI configuration register, performs a bitwise
> > + AND, and writes the result back to the bit field in the 8-bit register.
> > +
> > + Reads the 8-bit PCI configuration register specified by Address, performs
> a
> > + bitwise AND between the read result and the value specified by
> AndData, and
> > + writes the result to the 8-bit PCI configuration register specified by
> > + Address. The value written to the PCI configuration register is returned.
> > + This function must guarantee that all PCI read and write operations are
> > + serialized. Extra left bits in AndData are stripped.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If StartBit is greater than 7, then ASSERT().
> > + If EndBit is greater than 7, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > + If AndData is larger than the bitmask value range specified by StartBit
> and
> > EndBit, then ASSERT().
> > +
> > + @param Address The PCI configuration register to write.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..7.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..7.
> > + @param AndData The value to AND with the PCI configuration register.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciBitFieldAnd8 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit,
> > + IN UINT8 AndData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldAnd8 (Address, StartBit, EndBit, AndData) :
> > + PciCf8BitFieldAnd8 (Address, StartBit, EndBit, AndData);
> > +}
> > +
> > +/**
> > + Reads a bit field in an 8-bit port, performs a bitwise AND followed by a
> > + bitwise OR, and writes the result back to the bit field in the
> > + 8-bit port.
> > +
> > + Reads the 8-bit PCI configuration register specified by Address, performs
> a
> > + bitwise AND followed by a bitwise OR between the read result and
> > + the value specified by AndData, and writes the result to the 8-bit PCI
> > + configuration register specified by Address. The value written to the PCI
> > + configuration register is returned. This function must guarantee that all
> PCI
> > + read and write operations are serialized. Extra left bits in both AndData
> and
> > + OrData are stripped.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If StartBit is greater than 7, then ASSERT().
> > + If EndBit is greater than 7, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > + If AndData is larger than the bitmask value range specified by StartBit
> and
> > EndBit, then ASSERT().
> > + If OrData is larger than the bitmask value range specified by StartBit and
> > EndBit, then ASSERT().
> > +
> > + @param Address The PCI configuration register to write.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..7.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..7.
> > + @param AndData The value to AND with the PCI configuration register.
> > + @param OrData The value to OR with the result of the AND operation.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT8
> > +EFIAPI
> > +PciBitFieldAndThenOr8 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit,
> > + IN UINT8 AndData,
> > + IN UINT8 OrData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData,
> > OrData) :
> > + PciCf8BitFieldAndThenOr8 (Address, StartBit, EndBit, AndData,
> OrData);
> > +}
> > +
> > +/**
> > + Reads a 16-bit PCI configuration register.
> > +
> > + Reads and returns the 16-bit PCI configuration register specified by
> Address.
> > + This function must guarantee that all PCI read and write operations are
> > + serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > +
> > + @return The read value from the PCI configuration register.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciRead16 (
> > + IN UINTN Address
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressRead16 (Address) :
> > + PciCf8Read16 (Address);
> > +}
> > +
> > +/**
> > + Writes a 16-bit PCI configuration register.
> > +
> > + Writes the 16-bit PCI configuration register specified by Address with the
> > + value specified by Value. Value is returned. This function must
> guarantee
> > + that all PCI read and write operations are serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > + @param Value The value to write.
> > +
> > + @return The value written to the PCI configuration register.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciWrite16 (
> > + IN UINTN Address,
> > + IN UINT16 Value
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressWrite16 (Address, Value) :
> > + PciCf8Write16 (Address, Value);
> > +}
> > +
> > +/**
> > + Performs a bitwise OR of a 16-bit PCI configuration register with
> > + a 16-bit value.
> > +
> > + Reads the 16-bit PCI configuration register specified by Address,
> performs a
> > + bitwise OR between the read result and the value specified by
> > + OrData, and writes the result to the 16-bit PCI configuration register
> > + specified by Address. The value written to the PCI configuration register
> is
> > + returned. This function must guarantee that all PCI read and write
> operations
> > + are serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > + @param OrData The value to OR with the PCI configuration register.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciOr16 (
> > + IN UINTN Address,
> > + IN UINT16 OrData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressOr16 (Address, OrData) :
> > + PciCf8Or16 (Address, OrData);
> > +}
> > +
> > +/**
> > + Performs a bitwise AND of a 16-bit PCI configuration register with a 16-
> bit
> > + value.
> > +
> > + Reads the 16-bit PCI configuration register specified by Address,
> performs a
> > + bitwise AND between the read result and the value specified by
> AndData, and
> > + writes the result to the 16-bit PCI configuration register specified by
> > + Address. The value written to the PCI configuration register is returned.
> > + This function must guarantee that all PCI read and write operations are
> > + serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > + @param AndData The value to AND with the PCI configuration register.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciAnd16 (
> > + IN UINTN Address,
> > + IN UINT16 AndData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressAnd16 (Address, AndData) :
> > + PciCf8And16 (Address, AndData);
> > +}
> > +
> > +/**
> > + Performs a bitwise AND of a 16-bit PCI configuration register with a 16-
> bit
> > + value, followed a bitwise OR with another 16-bit value.
> > +
> > + Reads the 16-bit PCI configuration register specified by Address,
> performs a
> > + bitwise AND between the read result and the value specified by
> AndData,
> > + performs a bitwise OR between the result of the AND operation and
> > + the value specified by OrData, and writes the result to the 16-bit PCI
> > + configuration register specified by Address. The value written to the PCI
> > + configuration register is returned. This function must guarantee that all
> PCI
> > + read and write operations are serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > + @param AndData The value to AND with the PCI configuration register.
> > + @param OrData The value to OR with the result of the AND operation.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciAndThenOr16 (
> > + IN UINTN Address,
> > + IN UINT16 AndData,
> > + IN UINT16 OrData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressAndThenOr16 (Address, AndData, OrData) :
> > + PciCf8AndThenOr16 (Address, AndData, OrData);
> > +}
> > +
> > +/**
> > + Reads a bit field of a PCI configuration register.
> > +
> > + Reads the bit field in a 16-bit PCI configuration register. The bit field is
> > + specified by the StartBit and the EndBit. The value of the bit field is
> > + returned.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > + If StartBit is greater than 15, then ASSERT().
> > + If EndBit is greater than 15, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > +
> > + @param Address The PCI configuration register to read.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..15.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..15.
> > +
> > + @return The value of the bit field read from the PCI configuration
> register.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciBitFieldRead16 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldRead16 (Address, StartBit, EndBit) :
> > + PciCf8BitFieldRead16 (Address, StartBit, EndBit);
> > +}
> > +
> > +/**
> > + Writes a bit field to a PCI configuration register.
> > +
> > + Writes Value to the bit field of the PCI configuration register. The bit
> > + field is specified by the StartBit and the EndBit. All other bits in the
> > + destination PCI configuration register are preserved. The new value of
> the
> > + 16-bit register is returned.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > + If StartBit is greater than 15, then ASSERT().
> > + If EndBit is greater than 15, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > + If Value is larger than the bitmask value range specified by StartBit and
> EndBit,
> > then ASSERT().
> > +
> > + @param Address The PCI configuration register to write.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..15.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..15.
> > + @param Value The new value of the bit field.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciBitFieldWrite16 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit,
> > + IN UINT16 Value
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldWrite16 (Address, StartBit, EndBit, Value) :
> > + PciCf8BitFieldWrite16 (Address, StartBit, EndBit, Value);
> > +}
> > +
> > +/**
> > + Reads a bit field in a 16-bit PCI configuration, performs a bitwise OR, and
> > + writes the result back to the bit field in the 16-bit port.
> > +
> > + Reads the 16-bit PCI configuration register specified by Address,
> performs a
> > + bitwise OR between the read result and the value specified by
> > + OrData, and writes the result to the 16-bit PCI configuration register
> > + specified by Address. The value written to the PCI configuration register
> is
> > + returned. This function must guarantee that all PCI read and write
> operations
> > + are serialized. Extra left bits in OrData are stripped.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > + If StartBit is greater than 15, then ASSERT().
> > + If EndBit is greater than 15, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > + If OrData is larger than the bitmask value range specified by StartBit and
> > EndBit, then ASSERT().
> > +
> > + @param Address The PCI configuration register to write.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..15.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..15.
> > + @param OrData The value to OR with the PCI configuration register.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciBitFieldOr16 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit,
> > + IN UINT16 OrData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldOr16 (Address, StartBit, EndBit, OrData) :
> > + PciCf8BitFieldOr16 (Address, StartBit, EndBit, OrData);
> > +}
> > +
> > +/**
> > + Reads a bit field in a 16-bit PCI configuration register, performs a bitwise
> > + AND, and writes the result back to the bit field in the 16-bit register.
> > +
> > + Reads the 16-bit PCI configuration register specified by Address,
> performs a
> > + bitwise AND between the read result and the value specified by
> AndData, and
> > + writes the result to the 16-bit PCI configuration register specified by
> > + Address. The value written to the PCI configuration register is returned.
> > + This function must guarantee that all PCI read and write operations are
> > + serialized. Extra left bits in AndData are stripped.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > + If StartBit is greater than 15, then ASSERT().
> > + If EndBit is greater than 15, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > + If AndData is larger than the bitmask value range specified by StartBit
> and
> > EndBit, then ASSERT().
> > +
> > + @param Address The PCI configuration register to write.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..15.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..15.
> > + @param AndData The value to AND with the PCI configuration register.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciBitFieldAnd16 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit,
> > + IN UINT16 AndData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldAnd16 (Address, StartBit, EndBit, AndData) :
> > + PciCf8BitFieldAnd16 (Address, StartBit, EndBit, AndData);
> > +}
> > +
> > +/**
> > + Reads a bit field in a 16-bit port, performs a bitwise AND followed by a
> > + bitwise OR, and writes the result back to the bit field in the
> > + 16-bit port.
> > +
> > + Reads the 16-bit PCI configuration register specified by Address,
> performs a
> > + bitwise AND followed by a bitwise OR between the read result and
> > + the value specified by AndData, and writes the result to the 16-bit PCI
> > + configuration register specified by Address. The value written to the PCI
> > + configuration register is returned. This function must guarantee that all
> PCI
> > + read and write operations are serialized. Extra left bits in both AndData
> and
> > + OrData are stripped.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 16-bit boundary, then ASSERT().
> > + If StartBit is greater than 15, then ASSERT().
> > + If EndBit is greater than 15, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > + If AndData is larger than the bitmask value range specified by StartBit
> and
> > EndBit, then ASSERT().
> > + If OrData is larger than the bitmask value range specified by StartBit and
> > EndBit, then ASSERT().
> > +
> > + @param Address The PCI configuration register to write.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..15.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..15.
> > + @param AndData The value to AND with the PCI configuration register.
> > + @param OrData The value to OR with the result of the AND operation.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +PciBitFieldAndThenOr16 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit,
> > + IN UINT16 AndData,
> > + IN UINT16 OrData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData,
> > OrData) :
> > + PciCf8BitFieldAndThenOr16 (Address, StartBit, EndBit, AndData,
> OrData);
> > +}
> > +
> > +/**
> > + Reads a 32-bit PCI configuration register.
> > +
> > + Reads and returns the 32-bit PCI configuration register specified by
> Address.
> > + This function must guarantee that all PCI read and write operations are
> > + serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > +
> > + @return The read value from the PCI configuration register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciRead32 (
> > + IN UINTN Address
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressRead32 (Address) :
> > + PciCf8Read32 (Address);
> > +}
> > +
> > +/**
> > + Writes a 32-bit PCI configuration register.
> > +
> > + Writes the 32-bit PCI configuration register specified by Address with the
> > + value specified by Value. Value is returned. This function must
> guarantee
> > + that all PCI read and write operations are serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > + @param Value The value to write.
> > +
> > + @return The value written to the PCI configuration register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciWrite32 (
> > + IN UINTN Address,
> > + IN UINT32 Value
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressWrite32 (Address, Value) :
> > + PciCf8Write32 (Address, Value);
> > +}
> > +
> > +/**
> > + Performs a bitwise OR of a 32-bit PCI configuration register with
> > + a 32-bit value.
> > +
> > + Reads the 32-bit PCI configuration register specified by Address,
> performs a
> > + bitwise OR between the read result and the value specified by
> > + OrData, and writes the result to the 32-bit PCI configuration register
> > + specified by Address. The value written to the PCI configuration register
> is
> > + returned. This function must guarantee that all PCI read and write
> operations
> > + are serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > + @param OrData The value to OR with the PCI configuration register.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciOr32 (
> > + IN UINTN Address,
> > + IN UINT32 OrData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressOr32 (Address, OrData) :
> > + PciCf8Or32 (Address, OrData);
> > +}
> > +
> > +/**
> > + Performs a bitwise AND of a 32-bit PCI configuration register with a 32-
> bit
> > + value.
> > +
> > + Reads the 32-bit PCI configuration register specified by Address,
> performs a
> > + bitwise AND between the read result and the value specified by
> AndData, and
> > + writes the result to the 32-bit PCI configuration register specified by
> > + Address. The value written to the PCI configuration register is returned.
> > + This function must guarantee that all PCI read and write operations are
> > + serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > + @param AndData The value to AND with the PCI configuration register.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciAnd32 (
> > + IN UINTN Address,
> > + IN UINT32 AndData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressAnd32 (Address, AndData) :
> > + PciCf8And32 (Address, AndData);
> > +}
> > +
> > +/**
> > + Performs a bitwise AND of a 32-bit PCI configuration register with a 32-
> bit
> > + value, followed a bitwise OR with another 32-bit value.
> > +
> > + Reads the 32-bit PCI configuration register specified by Address,
> performs a
> > + bitwise AND between the read result and the value specified by
> AndData,
> > + performs a bitwise OR between the result of the AND operation and
> > + the value specified by OrData, and writes the result to the 32-bit PCI
> > + configuration register specified by Address. The value written to the PCI
> > + configuration register is returned. This function must guarantee that all
> PCI
> > + read and write operations are serialized.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > +
> > + @param Address The address that encodes the PCI Bus, Device,
> Function and
> > + Register.
> > + @param AndData The value to AND with the PCI configuration register.
> > + @param OrData The value to OR with the result of the AND operation.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciAndThenOr32 (
> > + IN UINTN Address,
> > + IN UINT32 AndData,
> > + IN UINT32 OrData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressAndThenOr32 (Address, AndData, OrData) :
> > + PciCf8AndThenOr32 (Address, AndData, OrData);
> > +}
> > +
> > +/**
> > + Reads a bit field of a PCI configuration register.
> > +
> > + Reads the bit field in a 32-bit PCI configuration register. The bit field is
> > + specified by the StartBit and the EndBit. The value of the bit field is
> > + returned.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > + If StartBit is greater than 31, then ASSERT().
> > + If EndBit is greater than 31, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > +
> > + @param Address The PCI configuration register to read.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..31.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..31.
> > +
> > + @return The value of the bit field read from the PCI configuration
> register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciBitFieldRead32 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldRead32 (Address, StartBit, EndBit) :
> > + PciCf8BitFieldRead32 (Address, StartBit, EndBit);
> > +}
> > +
> > +/**
> > + Writes a bit field to a PCI configuration register.
> > +
> > + Writes Value to the bit field of the PCI configuration register. The bit
> > + field is specified by the StartBit and the EndBit. All other bits in the
> > + destination PCI configuration register are preserved. The new value of
> the
> > + 32-bit register is returned.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > + If StartBit is greater than 31, then ASSERT().
> > + If EndBit is greater than 31, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > + If Value is larger than the bitmask value range specified by StartBit and
> EndBit,
> > then ASSERT().
> > +
> > + @param Address The PCI configuration register to write.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..31.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..31.
> > + @param Value The new value of the bit field.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciBitFieldWrite32 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit,
> > + IN UINT32 Value
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldWrite32 (Address, StartBit, EndBit, Value) :
> > + PciCf8BitFieldWrite32 (Address, StartBit, EndBit, Value);
> > +}
> > +
> > +/**
> > + Reads a bit field in a 32-bit PCI configuration, performs a bitwise OR, and
> > + writes the result back to the bit field in the 32-bit port.
> > +
> > + Reads the 32-bit PCI configuration register specified by Address,
> performs a
> > + bitwise OR between the read result and the value specified by
> > + OrData, and writes the result to the 32-bit PCI configuration register
> > + specified by Address. The value written to the PCI configuration register
> is
> > + returned. This function must guarantee that all PCI read and write
> operations
> > + are serialized. Extra left bits in OrData are stripped.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > + If StartBit is greater than 31, then ASSERT().
> > + If EndBit is greater than 31, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > + If OrData is larger than the bitmask value range specified by StartBit and
> > EndBit, then ASSERT().
> > +
> > + @param Address The PCI configuration register to write.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..31.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..31.
> > + @param OrData The value to OR with the PCI configuration register.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciBitFieldOr32 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit,
> > + IN UINT32 OrData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldOr32 (Address, StartBit, EndBit, OrData) :
> > + PciCf8BitFieldOr32 (Address, StartBit, EndBit, OrData);
> > +}
> > +
> > +/**
> > + Reads a bit field in a 32-bit PCI configuration register, performs a bitwise
> > + AND, and writes the result back to the bit field in the 32-bit register.
> > +
> > + Reads the 32-bit PCI configuration register specified by Address,
> performs a
> > + bitwise AND between the read result and the value specified by
> AndData, and
> > + writes the result to the 32-bit PCI configuration register specified by
> > + Address. The value written to the PCI configuration register is returned.
> > + This function must guarantee that all PCI read and write operations are
> > + serialized. Extra left bits in AndData are stripped.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > + If StartBit is greater than 31, then ASSERT().
> > + If EndBit is greater than 31, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > + If AndData is larger than the bitmask value range specified by StartBit
> and
> > EndBit, then ASSERT().
> > +
> > + @param Address The PCI configuration register to write.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..31.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..31.
> > + @param AndData The value to AND with the PCI configuration register.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciBitFieldAnd32 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit,
> > + IN UINT32 AndData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldAnd32 (Address, StartBit, EndBit, AndData) :
> > + PciCf8BitFieldAnd32 (Address, StartBit, EndBit, AndData);
> > +}
> > +
> > +/**
> > + Reads a bit field in a 32-bit port, performs a bitwise AND followed by a
> > + bitwise OR, and writes the result back to the bit field in the
> > + 32-bit port.
> > +
> > + Reads the 32-bit PCI configuration register specified by Address,
> performs a
> > + bitwise AND followed by a bitwise OR between the read result and
> > + the value specified by AndData, and writes the result to the 32-bit PCI
> > + configuration register specified by Address. The value written to the PCI
> > + configuration register is returned. This function must guarantee that all
> PCI
> > + read and write operations are serialized. Extra left bits in both AndData
> and
> > + OrData are stripped.
> > +
> > + If Address > 0x0FFFFFFF, then ASSERT().
> > + If Address is not aligned on a 32-bit boundary, then ASSERT().
> > + If StartBit is greater than 31, then ASSERT().
> > + If EndBit is greater than 31, then ASSERT().
> > + If EndBit is less than StartBit, then ASSERT().
> > + If AndData is larger than the bitmask value range specified by StartBit
> and
> > EndBit, then ASSERT().
> > + If OrData is larger than the bitmask value range specified by StartBit and
> > EndBit, then ASSERT().
> > +
> > + @param Address The PCI configuration register to write.
> > + @param StartBit The ordinal of the least significant bit in the bit field.
> > + Range 0..31.
> > + @param EndBit The ordinal of the most significant bit in the bit field.
> > + Range 0..31.
> > + @param AndData The value to AND with the PCI configuration register.
> > + @param OrData The value to OR with the result of the AND operation.
> > +
> > + @return The value written back to the PCI configuration register.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +PciBitFieldAndThenOr32 (
> > + IN UINTN Address,
> > + IN UINTN StartBit,
> > + IN UINTN EndBit,
> > + IN UINT32 AndData,
> > + IN UINT32 OrData
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData,
> > OrData) :
> > + PciCf8BitFieldAndThenOr32 (Address, StartBit, EndBit, AndData,
> OrData);
> > +}
> > +
> > +/**
> > + Reads a range of PCI configuration registers into a caller supplied buffer.
> > +
> > + Reads the range of PCI configuration registers specified by StartAddress
> and
> > + Size into the buffer specified by Buffer. This function only allows the PCI
> > + configuration registers from a single PCI function to be read. Size is
> > + returned. When possible 32-bit PCI configuration read cycles are used to
> read
> > + from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-
> bit
> > + and 16-bit PCI configuration read cycles may be used at the beginning
> and the
> > + end of the range.
> > +
> > + If StartAddress > 0x0FFFFFFF, then ASSERT().
> > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> > + If Size > 0 and Buffer is NULL, then ASSERT().
> > +
> > + @param StartAddress The starting address that encodes the PCI Bus,
> Device,
> > + Function and Register.
> > + @param Size The size in bytes of the transfer.
> > + @param Buffer The pointer to a buffer receiving the data read.
> > +
> > + @return Size
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +PciReadBuffer (
> > + IN UINTN StartAddress,
> > + IN UINTN Size,
> > + OUT VOID *Buffer
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressReadBuffer (StartAddress, Size, Buffer) :
> > + PciCf8ReadBuffer (StartAddress, Size, Buffer);
> > +}
> > +
> > +/**
> > + Copies the data in a caller supplied buffer to a specified range of PCI
> > + configuration space.
> > +
> > + Writes the range of PCI configuration registers specified by StartAddress
> and
> > + Size from the buffer specified by Buffer. This function only allows the PCI
> > + configuration registers from a single PCI function to be written. Size is
> > + returned. When possible 32-bit PCI configuration write cycles are used to
> > + write from StartAdress to StartAddress + Size. Due to alignment
> restrictions,
> > + 8-bit and 16-bit PCI configuration write cycles may be used at the
> beginning
> > + and the end of the range.
> > +
> > + If StartAddress > 0x0FFFFFFF, then ASSERT().
> > + If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
> > + If Size > 0 and Buffer is NULL, then ASSERT().
> > +
> > + @param StartAddress The starting address that encodes the PCI Bus,
> Device,
> > + Function and Register.
> > + @param Size The size in bytes of the transfer.
> > + @param Buffer The pointer to a buffer containing the data to write.
> > +
> > + @return Size written to StartAddress.
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +PciWriteBuffer (
> > + IN UINTN StartAddress,
> > + IN UINTN Size,
> > + IN VOID *Buffer
> > + )
> > +{
> > + return mRunningOnIch10 ?
> > + PciExpressWriteBuffer (StartAddress, Size, Buffer) :
> > + PciCf8WriteBuffer (StartAddress, Size, Buffer);
> > +}
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.c
> > new file mode 100644
> > index 0000000000..b1d7552792
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.c
> > @@ -0,0 +1,1579 @@
> > +/** @file
> > + ACPI Platform Driver
> > +
> > + Copyright (c) 2017 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
> A
> > DER *McfgTable;
> > +
> >
> EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_
> AD
> > DRESS_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_
> BA
> > SE_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_
> B
> > ASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
> > +
> >
> EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_RE
> VIS
> > ION,
> > + 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_H
> EA
> > DER) +
> > + sizeof
> >
> (EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_
> A
> > DDRESS_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_
> B
> > ASE_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
> Ta
> > bles/Facs/Facs.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/Facs/Facs.c
> > new file mode 100644
> > index 0000000000..a16c13466a
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/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) 2017 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
> Ta
> > bles/Fadt/Fadt.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/Fadt/Fadt.c
> > new file mode 100644
> > index 0000000000..8aa10a4a5b
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/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) 2017 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
> Ta
> > bles/Hpet/Hpet.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/Hpet/Hpet.c
> > new file mode 100644
> > index 0000000000..aa386ba149
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/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) 2017 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
> Ta
> > bles/Wsmt/Wsmt.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/Wsmt/Wsmt.c
> > new file mode 100644
> > index 0000000000..12e2feacb4
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/Wsmt/Wsmt.c
> > @@ -0,0 +1,46 @@
> > +/** @file
> > + ACPI WSMT table
> > +
> > + Copyright (c) 2017 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/
> Co
> > mponentName.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Co
> > mponentName.c
> > new file mode 100644
> > index 0000000000..dd9cc80e42
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Co
> > mponentName.c
> > @@ -0,0 +1,205 @@
> > +/** @file
> > + Component name for the QEMU video controller.
> > +
> > + Copyright (c) 2006 - 2010, 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/
> Dri
> > ver.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Dri
> > ver.c
> > new file mode 100644
> > index 0000000000..e49e7a465c
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Dri
> > ver.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/
> Dri
> > verSupportedEfiVersion.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Dri
> > verSupportedEfiVersion.c
> > new file mode 100644
> > index 0000000000..c2d82e7324
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Dri
> > verSupportedEfiVersion.c
> > @@ -0,0 +1,15 @@
> > +/** @file
> > + Driver supported version protocol for the QEMU video driver.
> > +
> > + Copyright (c) 2007 - 2010 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/
> Go
> > p.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Go
> > p.c
> > new file mode 100644
> > index 0000000000..19ff5209d2
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Go
> > p.c
> > @@ -0,0 +1,417 @@
> > +/** @file
> > + Graphics Output Protocol functions for the QEMU video controller.
> > +
> > + Copyright (c) 2007 - 2018 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/
> Ini
> > tialize.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Ini
> > tialize.c
> > new file mode 100644
> > index 0000000000..fbf40e9eaf
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Ini
> > tialize.c
> > @@ -0,0 +1,341 @@
> > +/** @file
> > + Graphics Output Protocol functions for the QEMU video controller.
> > +
> > + Copyright (c) 2007 - 2010 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/
> Vb
> > eShim.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.c
> > new file mode 100644
> > index 0000000000..aa4648f813
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.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/Overrides/PcAtChipsetPkg/8259Interr
> u
> > ptControllerDxe/8259.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/8259.c
> > new file mode 100644
> > index 0000000000..b57bacdda4
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/8259.c
> > @@ -0,0 +1,622 @@
> > +/** @file
> > + This contains the installation function for the driver.
> > +
> > + Copyright (c) 2005 - 2018 Intel Corporation. All rights reserved. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include "8259.h"
> > +
> > +//
> > +// Global for the Legacy 8259 Protocol that is produced by this driver
> > +//
> > +EFI_LEGACY_8259_PROTOCOL mInterrupt8259 = {
> > + Interrupt8259SetVectorBase,
> > + Interrupt8259GetMask,
> > + Interrupt8259SetMask,
> > + Interrupt8259SetMode,
> > + Interrupt8259GetVector,
> > + Interrupt8259EnableIrq,
> > + Interrupt8259DisableIrq,
> > + Interrupt8259GetInterruptLine,
> > + Interrupt8259EndOfInterrupt
> > +};
> > +
> > +//
> > +// Global for the handle that the Legacy 8259 Protocol is installed
> > +//
> > +EFI_HANDLE m8259Handle = NULL;
> > +
> > +UINT8 mMasterBase = 0xff;
> > +UINT8 mSlaveBase = 0xff;
> > +EFI_8259_MODE mMode = Efi8259ProtectedMode;
> > +UINT16 mProtectedModeMask = 0xffff;
> > +UINT16 mLegacyModeMask;
> > +UINT16 mProtectedModeEdgeLevel = 0x0000;
> > +UINT16 mLegacyModeEdgeLevel;
> > +
> > +//
> > +// Worker Functions
> > +//
> > +
> > +/**
> > + Write to mask and edge/level triggered registers of master and slave
> 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));
> > +}
> > +
> > +/**
> > + Read from mask and edge/level triggered registers of master and slave
> PICs.
> > +
> > + @param[out] Mask low byte for master PIC mask register,
> > + high byte for slave PIC mask register.
> > + @param[out] EdgeLevel low byte for master PIC edge/level triggered
> > register,
> > + high byte for slave PIC edge/level triggered register.
> > +
> > +**/
> > +VOID
> > +Interrupt8259ReadMask (
> > + OUT UINT16 *Mask,
> > + OUT UINT16 *EdgeLevel
> > + )
> > +{
> > + UINT16 MasterValue;
> > + UINT16 SlaveValue;
> > +
> > + if (Mask != NULL) {
> > + MasterValue = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
> > + SlaveValue = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
> > +
> > + *Mask = (UINT16) (MasterValue | (SlaveValue << 8));
> > + }
> > +
> > + if (EdgeLevel != NULL) {
> > + MasterValue = IoRead8
> > (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_MASTER);
> > + SlaveValue = IoRead8
> > (LEGACY_8259_EDGE_LEVEL_TRIGGERED_REGISTER_SLAVE);
> > +
> > + *EdgeLevel = (UINT16) (MasterValue | (SlaveValue << 8));
> > + }
> > +}
> > +
> > +//
> > +// Legacy 8259 Protocol Interface Functions
> > +//
> > +
> > +/**
> > + Sets the base address for the 8259 master and slave PICs.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> > + @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
> > + @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
> > +
> > + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> > + @retval EFI_DEVICE_ERROR There was an error while writing to the
> 8259
> > PIC.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259SetVectorBase (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN UINT8 MasterBase,
> > + IN UINT8 SlaveBase
> > + )
> > +{
> > + UINT8 Mask;
> > + EFI_TPL OriginalTpl;
> > +
> > + OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> > + //
> > + // Set vector base for slave PIC
> > + //
> > + if (SlaveBase != mSlaveBase) {
> > + mSlaveBase = SlaveBase;
> > +
> > + //
> > + // Initialization sequence is needed for setting vector base.
> > + //
> > +
> > + //
> > + // Preserve interrtup mask register before initialization sequence
> > + // because it will be cleared during initialization
> > + //
> > + Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_SLAVE);
> > +
> > + //
> > + // ICW1: cascade mode, ICW4 write required
> > + //
> > + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE, 0x11);
> > +
> > + //
> > + // ICW2: new vector base (must be multiple of 8)
> > + //
> > + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, mSlaveBase);
> > +
> > + //
> > + // ICW3: slave indentification code must be 2
> > + //
> > + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x02);
> > +
> > + //
> > + // ICW4: fully nested mode, non-buffered mode, normal EOI, IA
> processor
> > + //
> > + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0x01);
> > +
> > + //
> > + // Restore interrupt mask register
> > + //
> > + IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, Mask);
> > + }
> > +
> > + //
> > + // Set vector base for master PIC
> > + //
> > + if (MasterBase != mMasterBase) {
> > + mMasterBase = MasterBase;
> > +
> > + //
> > + // Initialization sequence is needed for setting vector base.
> > + //
> > +
> > + //
> > + // Preserve interrtup mask register before initialization sequence
> > + // because it will be cleared during initialization
> > + //
> > + Mask = IoRead8 (LEGACY_8259_MASK_REGISTER_MASTER);
> > +
> > + //
> > + // ICW1: cascade mode, ICW4 write required
> > + //
> > + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER, 0x11);
> > +
> > + //
> > + // ICW2: new vector base (must be multiple of 8)
> > + //
> > + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, mMasterBase);
> > +
> > + //
> > + // ICW3: slave PIC is cascaded on IRQ2
> > + //
> > + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x04);
> > +
> > + //
> > + // ICW4: fully nested mode, non-buffered mode, normal EOI, IA
> processor
> > + //
> > + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0x01);
> > +
> > + //
> > + // Restore interrupt mask register
> > + //
> > + IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, Mask);
> > + }
> > +
> > + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE,
> LEGACY_8259_EOI);
> > + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER,
> > LEGACY_8259_EOI);
> > +
> > + gBS->RestoreTPL (OriginalTpl);
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > + Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> > instance.
> > + @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-
> IRQ15.
> > + @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-
> > IRQ15.
> > + @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-
> > IRQ15.
> > + @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for
> IRQ0-
> > IRQ15.
> > +
> > + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> > + @retval EFI_DEVICE_ERROR There was an error while reading the 8259
> PIC.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259GetMask (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + OUT UINT16 *LegacyMask, OPTIONAL
> > + OUT UINT16 *LegacyEdgeLevel, OPTIONAL
> > + OUT UINT16 *ProtectedMask, OPTIONAL
> > + OUT UINT16 *ProtectedEdgeLevel OPTIONAL
> > + )
> > +{
> > + if (LegacyMask != NULL) {
> > + *LegacyMask = mLegacyModeMask;
> > + }
> > +
> > + if (LegacyEdgeLevel != NULL) {
> > + *LegacyEdgeLevel = mLegacyModeEdgeLevel;
> > + }
> > +
> > + if (ProtectedMask != NULL) {
> > + *ProtectedMask = mProtectedModeMask;
> > + }
> > +
> > + if (ProtectedEdgeLevel != NULL) {
> > + *ProtectedEdgeLevel = mProtectedModeEdgeLevel;
> > + }
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > + Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> > instance.
> > + @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-
> IRQ15.
> > + @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-
> IRQ15.
> > + @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-
> IRQ15.
> > + @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-
> > IRQ15.
> > +
> > + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> > + @retval EFI_DEVICE_ERROR There was an error while writing the 8259
> PIC.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259SetMask (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN UINT16 *LegacyMask, OPTIONAL
> > + IN UINT16 *LegacyEdgeLevel, OPTIONAL
> > + IN UINT16 *ProtectedMask, OPTIONAL
> > + IN UINT16 *ProtectedEdgeLevel OPTIONAL
> > + )
> > +{
> > + if (LegacyMask != NULL) {
> > + mLegacyModeMask = *LegacyMask;
> > + }
> > +
> > + if (LegacyEdgeLevel != NULL) {
> > + mLegacyModeEdgeLevel = *LegacyEdgeLevel;
> > + }
> > +
> > + if (ProtectedMask != NULL) {
> > + mProtectedModeMask = *ProtectedMask;
> > + }
> > +
> > + if (ProtectedEdgeLevel != NULL) {
> > + mProtectedModeEdgeLevel = *ProtectedEdgeLevel;
> > + }
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > + Sets the mode of the PICs.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> > + @param[in] Mode 16-bit real or 32-bit protected mode.
> > + @param[in] Mask The value with which to set the interrupt mask.
> > + @param[in] EdgeLevel The value with which to set the edge/level mask.
> > +
> > + @retval EFI_SUCCESS The mode was set successfully.
> > + @retval EFI_INVALID_PARAMETER The mode was not set.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259SetMode (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_MODE Mode,
> > + IN UINT16 *Mask, OPTIONAL
> > + IN UINT16 *EdgeLevel OPTIONAL
> > + )
> > +{
> > + if (Mode == mMode) {
> > + return EFI_SUCCESS;
> > + }
> > +
> > + if (Mode == Efi8259LegacyMode) {
> > + //
> > + // In Efi8259ProtectedMode, mask and edge/level trigger registers
> should
> > + // be changed through this protocol, so we can track them in the
> > + // corresponding module variables.
> > + //
> > + Interrupt8259ReadMask (&mProtectedModeMask,
> > &mProtectedModeEdgeLevel);
> > +
> > + if (Mask != NULL) {
> > + //
> > + // Update the Mask for the new mode
> > + //
> > + mLegacyModeMask = *Mask;
> > + }
> > +
> > + if (EdgeLevel != NULL) {
> > + //
> > + // Update the Edge/Level triggered mask for the new mode
> > + //
> > + mLegacyModeEdgeLevel = *EdgeLevel;
> > + }
> > +
> > + mMode = Mode;
> > +
> > + //
> > + // Write new legacy mode mask/trigger level
> > + //
> > + Interrupt8259WriteMask (mLegacyModeMask,
> mLegacyModeEdgeLevel);
> > +
> > + return EFI_SUCCESS;
> > + }
> > +
> > + if (Mode == Efi8259ProtectedMode) {
> > + //
> > + // Save the legacy mode mask/trigger level
> > + //
> > + Interrupt8259ReadMask (&mLegacyModeMask,
> &mLegacyModeEdgeLevel);
> > + //
> > + // Always force Timer to be enabled after return from 16-bit code.
> > + // This always insures that on next entry, timer is counting.
> > + //
> > + mLegacyModeMask &= 0xFFFE;
> > +
> > + if (Mask != NULL) {
> > + //
> > + // Update the Mask for the new mode
> > + //
> > + mProtectedModeMask = *Mask;
> > + }
> > +
> > + if (EdgeLevel != NULL) {
> > + //
> > + // Update the Edge/Level triggered mask for the new mode
> > + //
> > + mProtectedModeEdgeLevel = *EdgeLevel;
> > + }
> > +
> > + mMode = Mode;
> > +
> > + //
> > + // Write new protected mode mask/trigger level
> > + //
> > + Interrupt8259WriteMask (mProtectedModeMask,
> > mProtectedModeEdgeLevel);
> > +
> > + return EFI_SUCCESS;
> > + }
> > +
> > + return EFI_INVALID_PARAMETER;
> > +}
> > +
> > +/**
> > + Translates the IRQ into a vector.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> > + @param[in] Irq IRQ0-IRQ15.
> > + @param[out] Vector The vector that is assigned to the IRQ.
> > +
> > + @retval EFI_SUCCESS The Vector that matches Irq was returned.
> > + @retval EFI_INVALID_PARAMETER Irq is not valid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259GetVector (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_IRQ Irq,
> > + OUT UINT8 *Vector
> > + )
> > +{
> > + if ((UINT32)Irq > Efi8259Irq15) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + if (Irq <= Efi8259Irq7) {
> > + *Vector = (UINT8) (mMasterBase + Irq);
> > + } else {
> > + *Vector = (UINT8) (mSlaveBase + (Irq - Efi8259Irq8));
> > + }
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > + Enables the specified IRQ.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> > + @param[in] Irq IRQ0-IRQ15.
> > + @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
> > +
> > + @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
> > + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259EnableIrq (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_IRQ Irq,
> > + IN BOOLEAN LevelTriggered
> > + )
> > +{
> > + if ((UINT32)Irq > Efi8259Irq15) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + mProtectedModeMask = (UINT16) (mProtectedModeMask & ~(1 << Irq));
> > + if (LevelTriggered) {
> > + mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel |
> (1 <<
> > Irq));
> > + } else {
> > + mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel &
> ~(1
> > << Irq));
> > + }
> > +
> > + Interrupt8259WriteMask (mProtectedModeMask,
> > mProtectedModeEdgeLevel);
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > + Disables the specified IRQ.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> > + @param[in] Irq IRQ0-IRQ15.
> > +
> > + @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
> > + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259DisableIrq (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_IRQ Irq
> > + )
> > +{
> > + if ((UINT32)Irq > Efi8259Irq15) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + mProtectedModeMask = (UINT16) (mProtectedModeMask | (1 << Irq));
> > +
> > + mProtectedModeEdgeLevel = (UINT16) (mProtectedModeEdgeLevel &
> ~(1 <<
> > Irq));
> > +
> > + Interrupt8259WriteMask (mProtectedModeMask,
> > mProtectedModeEdgeLevel);
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > + Reads the PCI configuration space to get the interrupt number that is
> assigned
> > to the card.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> > + @param[in] PciHandle PCI function for which to return the vector.
> > + @param[out] Vector IRQ number that corresponds to the interrupt
> line.
> > +
> > + @retval EFI_SUCCESS The interrupt line value was read successfully.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259GetInterruptLine (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_HANDLE PciHandle,
> > + OUT UINT8 *Vector
> > + )
> > +{
> > + EFI_PCI_IO_PROTOCOL *PciIo;
> > + UINT8 InterruptLine;
> > + EFI_STATUS Status;
> > +
> > + Status = gBS->HandleProtocol (
> > + PciHandle,
> > + &gEfiPciIoProtocolGuid,
> > + (VOID **) &PciIo
> > + );
> > + if (EFI_ERROR (Status)) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + PciIo->Pci.Read (
> > + PciIo,
> > + EfiPciIoWidthUint8,
> > + PCI_INT_LINE_OFFSET,
> > + 1,
> > + &InterruptLine
> > + );
> > + //
> > + // Interrupt line is same location for standard PCI cards, standard
> > + // bridge and CardBus bridge.
> > + //
> > + *Vector = InterruptLine;
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > + Issues the End of Interrupt (EOI) commands to PICs.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> > + @param[in] Irq The interrupt for which to issue the EOI command.
> > +
> > + @retval EFI_SUCCESS The EOI command was issued.
> > + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259EndOfInterrupt (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_IRQ Irq
> > + )
> > +{
> > + if ((UINT32)Irq > Efi8259Irq15) {
> > + return EFI_INVALID_PARAMETER;
> > + }
> > +
> > + if (Irq >= Efi8259Irq8) {
> > + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_SLAVE,
> LEGACY_8259_EOI);
> > + }
> > +
> > + IoWrite8 (LEGACY_8259_CONTROL_REGISTER_MASTER,
> > LEGACY_8259_EOI);
> > +
> > + return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > + Driver Entry point.
> > +
> > + @param[in] ImageHandle ImageHandle of the loaded driver.
> > + @param[in] SystemTable Pointer to the EFI System Table.
> > +
> > + @retval EFI_SUCCESS One or more of the drivers returned a success
> code.
> > + @retval !EFI_SUCCESS Error installing Legacy 8259 Protocol.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Install8259 (
> > + IN EFI_HANDLE ImageHandle,
> > + IN EFI_SYSTEM_TABLE *SystemTable
> > + )
> > +{
> > + EFI_STATUS Status;
> > + EFI_8259_IRQ Irq;
> > +
> > + //
> > + // Initialze mask values from PCDs
> > + //
> > + mLegacyModeMask = PcdGet16 (Pcd8259LegacyModeMask);
> > + mLegacyModeEdgeLevel = PcdGet16 (Pcd8259LegacyModeEdgeLevel);
> > +
> > + //
> > + // Clear all pending interrupt
> > + //
> > + for (Irq = Efi8259Irq0; Irq <= Efi8259Irq15; Irq++) {
> > + Interrupt8259EndOfInterrupt (&mInterrupt8259, Irq);
> > + }
> > +
> > + //
> > + // Set the 8259 Master base to 0x68 and the 8259 Slave base to 0x70
> > + //
> > + Status = Interrupt8259SetVectorBase (&mInterrupt8259,
> > PROTECTED_MODE_BASE_VECTOR_MASTER,
> > PROTECTED_MODE_BASE_VECTOR_SLAVE);
> > +
> > + //
> > + // Set all 8259 interrupts to edge triggered and disabled
> > + //
> > + Interrupt8259WriteMask (mProtectedModeMask,
> > mProtectedModeEdgeLevel);
> > +
> > + //
> > + // Install 8259 Protocol onto a new handle
> > + //
> > + Status = gBS->InstallProtocolInterface (
> > + &m8259Handle,
> > + &gEfiLegacy8259ProtocolGuid,
> > + EFI_NATIVE_INTERFACE,
> > + &mInterrupt8259
> > + );
> > + return Status;
> > +}
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridge.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridge.h
> > new file mode 100644
> > index 0000000000..3bf31067fa
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridge.h
> > @@ -0,0 +1,68 @@
> > +/** @file
> > + Header file of OVMF instance of PciHostBridgeLib.
> > +
> > + Copyright (c) 2016 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/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridgeLib.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridgeLib.inf
> > new file mode 100644
> > index 0000000000..8c6de3dca6
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/P
> ciH
> > ostBridgeLib/PciHostBridgeLib.inf
> > @@ -0,0 +1,50 @@
> > +## @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/SimicsOpenBoardPkg.dec
> > +
> > +[LibraryClasses]
> > + BaseMemoryLib
> > + DebugLib
> > + DevicePathLib
> > + MemoryAllocationLib
> > + PciLib
> > +
> > +[Pcd]
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> > + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/BdsPlatform.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/BdsPlatform.h
> > new file mode 100644
> > index 0000000000..1fb031b752
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/BdsPlatform.h
> > @@ -0,0 +1,156 @@
> > +/** @file
> > + Platform BDS customizations include file.
> > +
> > + Copyright (c) 2006 - 2017 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
> > + );
> > +
> > +#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/PlatformBootManagerLib.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/PlatformBootManagerLib.inf
> > new file mode 100644
> > index 0000000000..55da35e87d
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Library/Pl
> atf
> > ormBootManagerLib/PlatformBootManagerLib.inf
> > @@ -0,0 +1,69 @@
> > +## @file
> > +# Platform BDS customizations library.
> > +#
> > +# Copyright (c) 2007 - 2018 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/SimicsOpenBoardPkg.dec
> > + OvmfPkg/OvmfPkg.dec
> > +
> > +[LibraryClasses]
> > + BaseLib
> > + MemoryAllocationLib
> > + UefiBootServicesTableLib
> > + BaseMemoryLib
> > + DebugLib
> > + PcdLib
> > + UefiBootManagerLib
> > + BootLogoLib
> > + DevicePathLib
> > + PciLib
> > + NvVarsFileLib
> > + LoadLinuxLib
> > + UefiLib
> > +
> > +[Pcd]
> > + gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent
> > + gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> > + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
> > + gSimicsX58PkgTokenSpaceGuid.PcdShellFile
> > +
> > +[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/Overrides/MdeModulePkg/Logo/Log
> o.b
> > mp
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.b
> > mp
> > new file mode 100644
> > index
> > 0000000000000000000000000000000000000000..86d7030833a096f54539
> > 3735d931d9f4f2fbf8c0
> > 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|9R
> f
> > @{
> >
> 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+Uwxe4Bj5
> U
> > 1+
> >
> zJNV<fsLOyKaN}*L9!@<z9mh8h<ni$wkx9P7lK%h4Z%*B<7Jsrp4EO5e<5xcS!o
> h
> > 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
> D
> > W#
> > 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&V
> q
> > k}Yl
> >
> z@AY!xHNnH@N%pU<a<nu~HUmE#yNG;vNkH|7S}oL&{>V4s^ECYzID`Mbp
> Ms
> > Hs!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{
> s
> > 5Us
> > 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*AdsRk
> D
> > KJvp4
> >
> zCm;S4$mS{S0Q*XVe}%Ys?dtt2B$q2SM)p<m;qHcx>;OAaaYNG3l=>gnf&eMd
> p2
> > >%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~Wy
> q
> > 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|0
> W
> > }|?
> > 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<GTTt
> z
> > +&%C
> >
> zTsa&|c>Ceh<rrRt|D9JvT91IkL4=qT(5IEYf=6Co1^EcD5MYHQ!UiP2hn@=@IB
> R
> > %-
> > 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
> }x
> > H
> >
> z6kzQ<12?5q%15B;<2Rp2goEuu#RszFDuKTj<+Lo4#qq;+9<1JRT*wE$iSJUtWf
> h-
> > 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;!`le
> F
> > gjd
> >
> z4HR)*!k?qKx;|PdpMU`Nmq`9nK4SH*HHaGG<}M)F)eo&fP{!^FfI#fO3U8GJ@
> R
> > yE}
> >
> zUJ`v%LnnY2z<Wud!}_DLA6|mT?yegpIXKuI+&!Qy1?<kDTYNMA2RQxi7(~crlK
> 3
> > +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`2ZaJp
> b
> > 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+f
> U
> > ^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{32K
> q;
> > 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>tq54T5S1LGn
> X
> > 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`HWVKEHZa85
> v
> > Gi
> >
> zt%YN~UOX$Vd$6sI{Rq8oH61;hk?dW~x8TNl?e^Q)gDlVX>PG)6s(|%+dH+0ae
> R
> > ?+8
> >
> zLRGET#fNG=pd0k(l;RuCi~034n33M)HaNoI{OZ}{cz?M{&)Qk^z^VNH?1_i$>E
> N~
> > 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
> H
> > k9y
> > 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#>@
> h
> > Ag0B
> > 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
> W
> > LO
> > 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$vS3
> K
> > 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
> T
> > 3i
> >
> 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&h
> M
> > #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(eng
> i!
> > 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*HPy8DT
> q
> > 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>_
> > pcCU
> >
> zaYL*oX+Ama8^$T8?IUIPIn}}A1wlW%5Xk40Te4mmN~bA_sfshwdH_<YM?;?c
> u
> > n1%}
> > 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
> R
> > PfI4bJ
> > 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%p5
> P
> > 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=ISTIZmk
> 1
> > 1n
> >
> zBeo{euhu>j*@5>@q&8cxx%`xMxL=*F4ajkTNouWz<0@Z!d_ZTR_^>{+voM4
> X
> > f6<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;Yf7uPTcSG
> H
> > 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
> C
> > VC
> > 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|19D
> j
> > 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
> p
> > qN
> > 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
> z
> > z;Fg
> >
> z(UU<TD3b5cKiZ<bxttseP|GXh@oWnv+5M<{C4sVlhICi;^3KgzgS|G0y%rvMSIt
> N
> > x
> >
> 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)HLrlyFC
> F
> >
> 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
> E
> > zabu
> > 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#bD
> l
> > 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>_c
> C
> > k`?a
> >
> zN!mEkr}z;A5cMwsBFEuJ(v_ADdp`+rA_=VJRqNOyEYc=97|R{=kfT>(nG<R2<J_
> v
> > 8
> > 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>Rvx7Cz5
> kI
> > 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
> 7
> > PV
> >
> zvH6kM`h_GvCr#sz2LGy5I*2M9gdb8N2#dNI*?mfM#gr!ECO;%S5c#ZFhEfC<^
> N
> > 8-|
> >
> 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
> c
> > l-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
> H
> > hU<^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*4JIotb1dh
> d
> > 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=aFVbWUy
> a
> > 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
> G
> > SQXu
> >
> zbWoxoX1R_TxW5)cqX&)b$#nXHdK(?Fs(;PnJ+98apgGOdm7|w}<WSTjyyp}7!
> 2
> > `Kn
> >
> zjro0+DW6vAT2s87+SXvE%}03kYHYfDgxtD&O=grpwgs)%9BW6oOlne+G^#va
> G
> > 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#cQu
> > pq
> >
> zX;_GnC+Wz^2rMGCBWtF$UmA6w<hrOeQ&&TTPY!7rLsim&oW&@G3a8Nc7
> > Q^%~7b+YL
> > z*z-
> >
> @G`+C&Z5wVrzW3O1MML3vk&=UwHrb~FcWRee}N22+uw8gA1soZd48E7>!l
> d
> > >Q+
> >
> zsP9>?qB~4s9Ohh!BhrWs<jQ(v925%{BKEGwZBU3$@yh4~f+4$9l(mK5^i(?uR
> G
> > 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)s
> z
> >
> z#06Kzg)C60Xy8wJ!qBXV!b)U3WrIg3K)1iNGSmzDogW3t_&&=ry6V2TwHts42
> g
> > ?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*}FK
> 3
> > 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$q
> Y
> > 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{i
> G
> > 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;>nibBw
> V
> > 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
> h
> > 0x
> > 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=u6
> w
> > ;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>zM
> Y
> > J#!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;
> 1
> > y
> >
> zv#nH+Dm%Ab4Bwt&HJ`$q!R6&>ba{1iKbhAz1YT%kL+eo8=YChMvhdi4HZ13
> py
> > 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%ah7VB
> O
> > Y4
> >
> z(Y$TKzJ<J=gNJ^gBA_sfu}}9Z=354HEKK*k*S!&$B(%S5KF_V06KimjU+smdwE?
> G
> > g
> >
> zgdpm?(O%cKDWC4sWA<tteL1ZS8q{JQAFM=bj{|J2N93s?wEmXoYT6f&Frpd|
> c-
> > T!u
> >
> ziY5O_c}uj8QS9VyM?+Yct5nP{S?!(6X?_!#tzrwL>F*>WhR1#kQn!PdHjbvEG>E
> g
> > 6
> >
> za&cUBIx7Ui7Nd5UG?cPdOsvfXtY_O>k;TDR=r**Z#iOn{fh_3HFQG@7fUP~|*
> N
> > yv3
> > 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?7t0Oo3
> > y|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+0EXJc
> > p@|
> >
> 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>#tu
> b
> > 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*hrN
> y
> > 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?NQMuKA2njSMlN
> 7
> > 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^DoB
> z
> > 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#H
> k
> > 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^~p8
> u
> > 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
> M
> > Lk
> > TuM~Ktz$*n_Dey{xHWc`O(cS1K
> >
> > literal 0
> > HcmV?d00001
> >
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.id
> > f
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.i
> > df
> > new file mode 100644
> > index 0000000000..1f79332020
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.i
> > df
> > @@ -0,0 +1,10 @@
> > +// /** @file
> > +// Platform Logo image definition file.
> > +//
> > +// Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
> > +//
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +// **/
> > +
> > +#image IMG_LOGO Logo.bmp
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.in
> > f
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.i
> > nf
> > new file mode 100644
> > index 0000000000..3380f3c1d5
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.i
> > nf
> > @@ -0,0 +1,28 @@
> > +## @file
> > +# The default logo bitmap picture shown on setup screen, which is
> > corresponding to gEfiDefaultBmpLogoGuid.
> > +#
> > +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > + INF_VERSION = 0x00010005
> > + BASE_NAME = Logo
> > + MODULE_UNI_FILE = Logo.uni
> > + FILE_GUID = 7BB28B99-61BB-11D5-9A5D-0090273FC14D
> > + 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 ARM AARCH64
> > +#
> > +
> > +[Binaries]
> > + BIN|Logo.bmp|*
> > +
> > +[UserExtensions.TianoCore."ExtraFiles"]
> > + LogoExtra.uni
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.u
> > ni
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.u
> > ni
> > new file mode 100644
> > index 0000000000..9d1bbaffa9
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> o.u
> > ni
> > @@ -0,0 +1,16 @@
> > +// /** @file
> > +// The default logo bitmap picture shown on setup screen, which is
> > corresponding to gEfiDefaultBmpLogoGuid.
> > +//
> > +// This module provides the default logo bitmap picture shown on setup
> > screen, which corresponds to gEfiDefaultBmpLogoGuid.
> > +//
> > +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> > +//
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +// **/
> > +
> > +
> > +#string STR_MODULE_ABSTRACT #language en-US "Provides the
> default
> > logo bitmap picture shown on setup screen, which corresponds to
> > gEfiDefaultBmpLogoGuid"
> > +
> > +#string STR_MODULE_DESCRIPTION #language en-US "This module
> > provides the default logo bitmap picture shown on setup screen, which
> > corresponds to gEfiDefaultBmpLogoGuid."
> > +
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xe.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xe.inf
> > new file mode 100644
> > index 0000000000..01102b138f
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xe.inf
> > @@ -0,0 +1,55 @@
> > +## @file
> > +# The default logo bitmap picture shown on setup screen.
> > +#
> > +# Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > + INF_VERSION = 0x00010005
> > + BASE_NAME = LogoDxe
> > + MODULE_UNI_FILE = LogoDxe.uni
> > + FILE_GUID = F74D20EE-37E7-48FC-97F7-9B1047749C69
> > + MODULE_TYPE = DXE_DRIVER
> > + VERSION_STRING = 1.0
> > +
> > + ENTRY_POINT = InitializeLogo
> > +#
> > +# This flag specifies whether HII resource section is generated into PE
> image.
> > +#
> > + UEFI_HII_RESOURCE_SECTION = TRUE
> > +
> > +#
> > +# The following information is for reference only and not required by the
> build
> > tools.
> > +#
> > +# VALID_ARCHITECTURES = IA32 X64
> > +#
> > +
> > +[Sources]
> > + Logo.bmp
> > + Logo.c
> > + Logo.idf
> > +
> > +[Packages]
> > + MdeModulePkg/MdeModulePkg.dec
> > + MdePkg/MdePkg.dec
> > +
> > +[LibraryClasses]
> > + UefiBootServicesTableLib
> > + UefiDriverEntryPoint
> > + DebugLib
> > +
> > +[Protocols]
> > + gEfiHiiDatabaseProtocolGuid ## CONSUMES
> > + gEfiHiiImageExProtocolGuid ## CONSUMES
> > + gEfiHiiPackageListProtocolGuid ## PRODUCES CONSUMES
> > + gEdkiiPlatformLogoProtocolGuid ## PRODUCES
> > +
> > +[Depex]
> > + gEfiHiiDatabaseProtocolGuid AND
> > + gEfiHiiImageExProtocolGuid
> > +
> > +[UserExtensions.TianoCore."ExtraFiles"]
> > + LogoDxeExtra.uni
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xe.uni
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xe.uni
> > new file mode 100644
> > index 0000000000..9635701b60
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xe.uni
> > @@ -0,0 +1,16 @@
> > +// /** @file
> > +// The default logo bitmap picture shown on setup screen.
> > +//
> > +// This module provides the default logo bitmap picture shown on setup
> > screen, through EDKII Platform Logo protocol.
> > +//
> > +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> > +//
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +// **/
> > +
> > +
> > +#string STR_MODULE_ABSTRACT #language en-US "Provides the
> default
> > logo bitmap picture shown on setup screen."
> > +
> > +#string STR_MODULE_DESCRIPTION #language en-US "This module
> > provides the default logo bitmap picture shown on setup screen, through
> EDKII
> > Platform Logo protocol."
> > +
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xeExtra.uni
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xeExtra.uni
> > new file mode 100644
> > index 0000000000..c6ea34b81d
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oD
> > xeExtra.uni
> > @@ -0,0 +1,14 @@
> > +// /** @file
> > +// Logo Localized Strings and Content
> > +//
> > +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> > +//
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +// **/
> > +
> > +#string STR_PROPERTIES_MODULE_NAME
> > +#language en-US
> > +"Logo Image File"
> > +
> > +
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oEx
> > tra.uni
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oEx
> > tra.uni
> > new file mode 100644
> > index 0000000000..041179fb75
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdeModulePkg/Logo/Log
> oEx
> > tra.uni
> > @@ -0,0 +1,14 @@
> > +// /** @file
> > +// Logo Localized Strings and Content
> > +//
> > +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> > +//
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +// **/
> > +
> > +#string STR_PROPERTIES_MODULE_NAME
> > +#language en-US
> > +"Logo Image File"
> > +
> > +
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLi
> bCf
> > 8/DxePciLibX58Ich10.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLi
> bCf
> > 8/DxePciLibX58Ich10.inf
> > new file mode 100644
> > index 0000000000..e5ca95e20e
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MdePkg/Library/BasePciLi
> bCf
> > 8/DxePciLibX58Ich10.inf
> > @@ -0,0 +1,40 @@
> > +## @file
> > +# An instance of the PCI Library that is based on both the PCI CF8 Library
> and
> > +# the PCI Express Library.
> > +#
> > +# This PciLib instance caches the SimicsX58 platform type (X58-ICH10) in
> > +# its entry point function, then delegates function calls to one of the
> > +# PciCf8Lib or PciExpressLib "backends" as appropriate.
> > +#
> > +# Copyright (C) 2016, Red Hat, Inc.
> > +# Copyright (c) 2007 - 2014 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > + INF_VERSION = 0x00010005
> > + BASE_NAME = DxePciLibX58Ich10
> > + FILE_GUID = FC214B5D-B5B5-4E54-9B28-5E94532E5E2A
> > + MODULE_TYPE = BASE
> > + VERSION_STRING = 1.0
> > + LIBRARY_CLASS = PciLib|DXE_DRIVER DXE_RUNTIME_DRIVER
> > SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION
> > + CONSTRUCTOR = InitializeConfigAccessMethod
> > +
> > +# VALID_ARCHITECTURES = IA32 X64
> > +
> > +[Sources]
> > + PciLib.c
> > +
> > +[Packages]
> > + MdePkg/MdePkg.dec
> > + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> > +
> > +[LibraryClasses]
> > + PcdLib
> > + PciCf8Lib
> > + PciExpressLib
> > +
> > +[Pcd]
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.h
> > new file mode 100644
> > index 0000000000..2deb2a88eb
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.h
> > @@ -0,0 +1,45 @@
> > +/** @file
> > + This is an implementation of the ACPI platform driver.
> > +
> > + Copyright (c) 2017 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
> Ta
> > bles/AcpiPlatform.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.inf
> > new file mode 100644
> > index 0000000000..b4b52b6622
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/MinPlatformPkg/Acpi/Acpi
> Ta
> > bles/AcpiPlatform.inf
> > @@ -0,0 +1,105 @@
> > +## @file
> > +# Component information file for AcpiPlatform module
> > +#
> > +# Copyright (c) 2017 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/
> Qe
> > mu.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Qe
> > mu.h
> > new file mode 100644
> > index 0000000000..f6ef44a14f
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Qe
> > mu.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/
> Qe
> > muVideoDxe.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Qe
> > muVideoDxe.inf
> > new file mode 100644
> > index 0000000000..8370559016
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Qe
> > muVideoDxe.inf
> > @@ -0,0 +1,73 @@
> > +## @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/SimicsOpenBoardPkg.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
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> > +
> gEfiMdeModulePkgTokenSpaceGuid.PcdNullPointerDetectionPropertyMask
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.asm
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.asm
> > new file mode 100644
> > index 0000000000..cb2a60d827
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.asm
> > @@ -0,0 +1,281 @@
> > +;------------------------------------------------------------------------------
> > +; @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/
> Vb
> > eShim.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.h
> > new file mode 100644
> > index 0000000000..cc9b6e14cd
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.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/
> Vb
> > eShim.sh
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.sh
> > new file mode 100644
> > index 0000000000..7669f8a219
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/OvmfPkg/QemuVideoDxe/
> Vb
> > eShim.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
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interr
> u
> > ptControllerDxe/8259.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/8259.h
> > new file mode 100644
> > index 0000000000..a9673f9c87
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/8259.h
> > @@ -0,0 +1,218 @@
> > +/** @file
> > + Driver implementing the Tiano Legacy 8259 Protocol
> > +
> > +Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef _8259_H__
> > +#define _8259_H__
> > +
> > +#include <Protocol/Legacy8259.h>
> > +#include <Protocol/PciIo.h>
> > +
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/IoLib.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/PcdLib.h>
> > +
> > +#include <IndustryStandard/Pci.h>
> > +
> > +// 8259 Hardware definitions
> > +
> > +#define LEGACY_MODE_BASE_VECTOR_MASTER 0x08
> > +#define LEGACY_MODE_BASE_VECTOR_SLAVE 0x70
> > +
> > +#define PROTECTED_MODE_BASE_VECTOR_MASTER 0x68
> > +#define PROTECTED_MODE_BASE_VECTOR_SLAVE 0x70
> > +
> > +#define LEGACY_8259_CONTROL_REGISTER_MASTER 0x20
> > +#define LEGACY_8259_MASK_REGISTER_MASTER 0x21
> > +#define LEGACY_8259_CONTROL_REGISTER_SLAVE 0xA0
> > +#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
> > +
> > +#define LEGACY_8259_EOI 0x20
> > +
> > +// Protocol Function Prototypes
> > +
> > +/**
> > + Sets the base address for the 8259 master and slave PICs.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> > + @param[in] MasterBase Interrupt vectors for IRQ0-IRQ7.
> > + @param[in] SlaveBase Interrupt vectors for IRQ8-IRQ15.
> > +
> > + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> > + @retval EFI_DEVICE_ERROR There was an error while writing to the
> 8259
> > PIC.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259SetVectorBase (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN UINT8 MasterBase,
> > + IN UINT8 SlaveBase
> > + );
> > +
> > +/**
> > + Gets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> > instance.
> > + @param[out] LegacyMask 16-bit mode interrupt mask for IRQ0-
> IRQ15.
> > + @param[out] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-
> > IRQ15.
> > + @param[out] ProtectedMask 32-bit mode interrupt mask for IRQ0-
> > IRQ15.
> > + @param[out] ProtectedEdgeLevel 32-bit mode edge/level mask for
> IRQ0-
> > IRQ15.
> > +
> > + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> > + @retval EFI_DEVICE_ERROR There was an error while reading the 8259
> PIC.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259GetMask (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + OUT UINT16 *LegacyMask, OPTIONAL
> > + OUT UINT16 *LegacyEdgeLevel, OPTIONAL
> > + OUT UINT16 *ProtectedMask, OPTIONAL
> > + OUT UINT16 *ProtectedEdgeLevel OPTIONAL
> > + );
> > +
> > +/**
> > + Sets the current 16-bit real mode and 32-bit protected-mode IRQ masks.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> > instance.
> > + @param[in] LegacyMask 16-bit mode interrupt mask for IRQ0-
> IRQ15.
> > + @param[in] LegacyEdgeLevel 16-bit mode edge/level mask for IRQ-
> IRQ15.
> > + @param[in] ProtectedMask 32-bit mode interrupt mask for IRQ0-
> IRQ15.
> > + @param[in] ProtectedEdgeLevel 32-bit mode edge/level mask for IRQ0-
> > IRQ15.
> > +
> > + @retval EFI_SUCCESS The 8259 PIC was programmed successfully.
> > + @retval EFI_DEVICE_ERROR There was an error while writing the 8259
> PIC.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259SetMask (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN UINT16 *LegacyMask, OPTIONAL
> > + IN UINT16 *LegacyEdgeLevel, OPTIONAL
> > + IN UINT16 *ProtectedMask, OPTIONAL
> > + IN UINT16 *ProtectedEdgeLevel OPTIONAL
> > + );
> > +
> > +/**
> > + Sets the mode of the PICs.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> > + @param[in] Mode 16-bit real or 32-bit protected mode.
> > + @param[in] Mask The value with which to set the interrupt mask.
> > + @param[in] EdgeLevel The value with which to set the edge/level mask.
> > +
> > + @retval EFI_SUCCESS The mode was set successfully.
> > + @retval EFI_INVALID_PARAMETER The mode was not set.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259SetMode (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_MODE Mode,
> > + IN UINT16 *Mask, OPTIONAL
> > + IN UINT16 *EdgeLevel OPTIONAL
> > + );
> > +
> > +/**
> > + Translates the IRQ into a vector.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> > + @param[in] Irq IRQ0-IRQ15.
> > + @param[out] Vector The vector that is assigned to the IRQ.
> > +
> > + @retval EFI_SUCCESS The Vector that matches Irq was returned.
> > + @retval EFI_INVALID_PARAMETER Irq is not valid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259GetVector (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_IRQ Irq,
> > + OUT UINT8 *Vector
> > + );
> > +
> > +/**
> > + Enables the specified IRQ.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> > + @param[in] Irq IRQ0-IRQ15.
> > + @param[in] LevelTriggered 0 = Edge triggered; 1 = Level triggered.
> > +
> > + @retval EFI_SUCCESS The Irq was enabled on the 8259 PIC.
> > + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259EnableIrq (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_IRQ Irq,
> > + IN BOOLEAN LevelTriggered
> > + );
> > +
> > +/**
> > + Disables the specified IRQ.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> > + @param[in] Irq IRQ0-IRQ15.
> > +
> > + @retval EFI_SUCCESS The Irq was disabled on the 8259 PIC.
> > + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259DisableIrq (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_IRQ Irq
> > + );
> > +
> > +/**
> > + Reads the PCI configuration space to get the interrupt number that is
> assigned
> > to the card.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL
> instance.
> > + @param[in] PciHandle PCI function for which to return the vector.
> > + @param[out] Vector IRQ number that corresponds to the interrupt
> line.
> > +
> > + @retval EFI_SUCCESS The interrupt line value was read successfully.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259GetInterruptLine (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_HANDLE PciHandle,
> > + OUT UINT8 *Vector
> > + );
> > +
> > +/**
> > + Issues the End of Interrupt (EOI) commands to PICs.
> > +
> > + @param[in] This Indicates the EFI_LEGACY_8259_PROTOCOL instance.
> > + @param[in] Irq The interrupt for which to issue the EOI command.
> > +
> > + @retval EFI_SUCCESS The EOI command was issued.
> > + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Interrupt8259EndOfInterrupt (
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_IRQ Irq
> > + );
> > +
> > +#endif
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interr
> u
> > ptControllerDxe/8259.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/8259.inf
> > new file mode 100644
> > index 0000000000..e66b21c914
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/8259.inf
> > @@ -0,0 +1,46 @@
> > +## @file
> > +# 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
> > +#
> > +# Copyright (c) 2005 - 2019, Intel Corporation. All rights reserved.<BR>
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > + INF_VERSION = 0x00010005
> > + BASE_NAME = Legacy8259
> > + MODULE_UNI_FILE = Legacy8259.uni
> > + FILE_GUID = 79CA4208-BBA1-4a9a-8456-E1E66A81484E
> > + MODULE_TYPE = DXE_DRIVER
> > + VERSION_STRING = 1.0
> > + ENTRY_POINT = Install8259
> > +
> > +[Sources]
> > + 8259.c
> > + 8259.h
> > +
> > +[Packages]
> > + MdePkg/MdePkg.dec
> > + PcAtChipsetPkg/PcAtChipsetPkg.dec
> > + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> > +
> > +[LibraryClasses]
> > + UefiBootServicesTableLib
> > + DebugLib
> > + UefiDriverEntryPoint
> > + IoLib
> > + PcdLib
> > +
> > +[Protocols]
> > + gEfiLegacy8259ProtocolGuid ## PRODUCES
> > + gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMES
> > +
> > +[Pcd]
> > + gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeMask ##
> > CONSUMES
> > + gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel ##
> > CONSUMES
> > +
> > +[Depex]
> > + TRUE
> > +
> > +[UserExtensions.TianoCore."ExtraFiles"]
> > + Legacy8259Extra.uni
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interr
> u
> > ptControllerDxe/Legacy8259.uni
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/Legacy8259.uni
> > new file mode 100644
> > index 0000000000..d035292419
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/Legacy8259.uni
> > @@ -0,0 +1,16 @@
> > +// /** @file
> > +// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
> > +//
> > +// 8259 Interrupt Controller driver that provides Legacy 8259 protocol.
> > +//
> > +// Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>
> > +//
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +// **/
> > +
> > +
> > +#string STR_MODULE_ABSTRACT #language en-US "8259 Interrupt
> > Controller driver that provides Legacy 8259 protocol"
> > +
> > +#string STR_MODULE_DESCRIPTION #language en-US "8259 Interrupt
> > Controller driver that provides Legacy 8259 protocol."
> > +
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Interr
> u
> > ptControllerDxe/Legacy8259Extra.uni
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/Legacy8259Extra.uni
> > new file mode 100644
> > index 0000000000..ee43f6923c
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Overrides/PcAtChipsetPkg/8259Inter
> ru
> > ptControllerDxe/Legacy8259Extra.uni
> > @@ -0,0 +1,14 @@
> > +// /** @file
> > +// Legacy8259 Localized Strings and Content
> > +//
> > +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> > +//
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +// **/
> > +
> > +#string STR_PROPERTIES_MODULE_NAME
> > +#language en-US
> > +"Legacy 8259 Interrupt Controller DXE Driver"
> > +
> > +
> > --
> > 2.16.2.windows.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 6/7] SimicsOpenBoardPkg: Add board module for QSP Build tip
2019-08-23 17:04 ` David Wei
@ 2019-08-26 22:59 ` Kubacki, Michael A
0 siblings, 0 replies; 37+ messages in thread
From: Kubacki, Michael A @ 2019-08-26 22:59 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Thanks for removing the batch files.
Regarding PcdNetworkEnable and PcdSmbiosEnable, any functionality in an advanced feature package should not be enabled unless Stage 6 is selected. I recommend binding these to gMinPlatformPkgTokenSpaceGuid.PcdBootStage now. If that is a very involved activity, I think a BZ can be filed to fix it after the package is committed.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 23, 2019 10:05 AM
> To: Kubacki, Michael A <michael.a.kubacki@intel.com>; 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>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 6/7] SimicsOpenBoardPkg: Add board
> module for QSP Build tip
>
> Hi Mike,
> Please see the updates online below. Please let me know if you have any more
> comments.
>
> Thanks
> David
>
> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Monday, August 19, 2019 6:05 PM
> To: Wei, David Y <david.y.wei@intel.com>; 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>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 6/7] SimicsOpenBoardPkg: Add board
> module for QSP Build tip
>
> Feedback I could not find already noted elsewhere:
>
> 1. Remove the batch build files:
> - GitEdk2X58ICH10.bat
> - bld.bat
> - prebuild.bat
>
> The changes must be built with the Python scripts.
> Ydwei: Will use platform Logo library to replace the EDK2 logo driver in order to
> avoid compile error by Python scripts.
> 2. General comment that applies to multiple files:
> Files such as "PlatformPkgBuildOption.dsc" should follow the pre-existing
> open board package
> naming convention. For example, "OpenBoardPkgBuildOption.dsc" in
> KabylakeOpenBoardPkg.
> Ydwei: done
> 3. The first commit line should be "SimicsOpenBoardPkg/BoardX58Ich10 to
> indicate the files relative
> to their location in that board directory.
> Ydwei: will do it when commit the patch.
> 4. Some build option macros in here seem unnecessary. For example,
> "PURLEY_FLAG". Can you please
> check and clean this up?
> Ydwei: done
> 5. PlatformPkgConfig.dsc: The following PCDs should not always be TRUE as
> they originate in the
> AdvancedFeaturePkg and should only be enabled for an advanced feature
> boot.
> - gAdvancedFeaturePkgTokenSpaceGuid.PcdNetworkEnable
> - gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosEnable
> Ydwei: They are required by SIMICS, and S3 resume also needed. I didn't make
> change.
> > -----Original Message-----
> > From: Wei, David Y
> > Sent: Friday, August 9, 2019 3:47 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-platform patch 6/7] SimicsOpenBoardPkg: 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>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> >
> > 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 +++++
> > .../BoardX58ICH10/GitEdk2X58ICH10.bat | 75 +++++
> > .../BoardInitLib/PeiBoardInitPostMemLib.inf | 36 +++
> > .../Library/BoardInitLib/PeiBoardInitPreMemLib.inf | 38 +++
> > .../Library/BoardInitLib/PeiX58ICH10InitLib.h | 16 ++
> > .../BoardX58ICH10/PlatformPkgBuildOption.dsc | 89 ++++++
> > .../BoardX58ICH10/PlatformPkgConfig.dsc | 56 ++++
> > .../BoardX58ICH10/PlatformPkgPcd.dsc | 283
> +++++++++++++++++++
> > .../BoardX58ICH10/SimicsX58Pkg.fdf.inc | 48 ++++
> > .../BoardX58ICH10/SimicsX58PkgIa32X64.dsc | 244
> +++++++++++++++++
> > .../BoardX58ICH10/SimicsX58PkgIa32X64.fdf | 303
> > +++++++++++++++++++++
> > .../BoardX58ICH10/VarStore.fdf.inc | 53 ++++
> > .../Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat | 139 ++++++++++
> > .../BoardX58ICH10/build_config.cfg | 31 +++
> > .../SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat | 198
> > ++++++++++++++
> > 20 files changed, 2000 insertions(+)
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiB
> > oardInitPostMemLib.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiB
> > oardInitPreMemLib.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX
> > 58ICH10Detect.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX
> > 58ICH10InitPostMemLib.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX
> > 58ICH10InitPreMemLib.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/DecomprScratchEnd.fdf.i
> > nc
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiB
> > oardInitPostMemLib.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiB
> > oardInitPreMemLib.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/PeiX
> > 58ICH10InitLib.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOption.
> > dsc
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58Pkg.fdf.inc
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.ds
> > c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.fdf
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/VarStore.fdf.inc
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
> >
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iBoardInitPostMemLib.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iBoardInitPostMemLib.c
> > new file mode 100644
> > index 0000000000..29df3d41ee
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iBoardInitPostMemLib.c
> > @@ -0,0 +1,44 @@
> > +/** @file
> > + Copyright (c) 2018 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/Pe
> > iBoardInitPreMemLib.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iBoardInitPreMemLib.c
> > new file mode 100644
> > index 0000000000..228fd696df
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iBoardInitPreMemLib.c
> > @@ -0,0 +1,110 @@
> > +/** @file
> > + Copyright (c) 2018 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/Pe
> > iX58ICH10Detect.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iX58ICH10Detect.c
> > new file mode 100644
> > index 0000000000..7305ce3181
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iX58ICH10Detect.c
> > @@ -0,0 +1,26 @@
> > +/** @file
> > + Copyright (c) 2018 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/Pe
> > iX58ICH10InitPostMemLib.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iX58ICH10InitPostMemLib.c
> > new file mode 100644
> > index 0000000000..002f63a434
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iX58ICH10InitPostMemLib.c
> > @@ -0,0 +1,34 @@
> > +/** @file
> > + Copyright (c) 2018 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/Pe
> > iX58ICH10InitPreMemLib.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iX58ICH10InitPreMemLib.c
> > new file mode 100644
> > index 0000000000..9f0dc91c8a
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iX58ICH10InitPreMemLib.c
> > @@ -0,0 +1,111 @@
> > +/** @file
> > + Copyright (c) 2018 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 <IndustryStandard/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.fd
> > f.inc
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/DecomprScratchEnd.fd
> > f.inc
> > new file mode 100644
> > index 0000000000..394875f205
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/DecomprScratchEnd.fd
> > f.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 +
> > gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize + 16 +
> > gSimicsX58PkgTokenSpaceGuid.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) +
> > gSimicsX58PkgTokenSpaceGuid.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 gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd =
> > $(DECOMP_SCRATCH_BASE) + $(DECOMP_SCRATCH_SIZE)
> > diff --git
> > a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
> > new file mode 100644
> > index 0000000000..48e9c6b09d
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/GitEdk2X58ICH10.bat
> > @@ -0,0 +1,75 @@
> > +@echo off
> > +@REM @file
> > +@REM Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> > +@REM
> > +@REM SPDX-License-Identifier: BSD-2-Clause-Patent
> > +@REM
> > +
> > +@echo off
> > +
> > +pushd ..\..\..\..\..\
> > +
> > +@REM Set WORKSPACE environment.
> > +set WORKSPACE=%cd%
> > +echo.
> > +echo Set WORKSPACE as: %WORKSPACE%
> > +echo.
> > +
> > +@REM Check whether Git has been installed and been added to system path.
> > +git --help >nul 2>nul
> > +if %ERRORLEVEL% NEQ 0 (
> > + echo.
> > + echo The 'git' command is not recognized.
> > + echo Please make sure that Git is installed and has been added to system
> path.
> > + echo.
> > + goto :EOF
> > +)
> > +
> > +@REM Create the Conf directory under WORKSPACE
> > +if not exist %WORKSPACE%\Conf (
> > + mkdir Conf
> > +)
> > +
> > +@REM Set other environments.
> > +@REM Basic Rule:
> > +@REM Platform override Silicon override Core
> > +@REM Source override Binary
> > +
> > +set PACKAGES_PATH=%WORKSPACE%\edk2-
> > platforms\Platform\Intel;%WORKSPACE%\edk2-
> > platforms\Silicon\Intel;%WORKSPACE%\edk2-
> > platforms\Drivers;%WORKSPACE%\edk2-non-
> > osi\Silicon\Intel;%WORKSPACE%\edk2;%WORKSPACE%
> > +
> > +set EDK_TOOLS_BIN=%WORKSPACE%\edk2-BaseTools-win32
> > +
> > +@if not defined PYTHON_HOME (
> > + @if exist C:\Python27 (
> > + set PYTHON_HOME=C:\Python27
> > + )
> > +)
> > +
> > +set EDK_SETUP_OPTION=
> > +@rem if python is installed, disable the binary base tools.
> > +if defined PYTHON_HOME (
> > + set EDK_TOOLS_BIN=
> > + set EDK_SETUP_OPTION=Rebuild
> > +)
> > +pushd %WORKSPACE%\edk2
> > +call edksetup.bat %EDK_SETUP_OPTION%
> > +popd
> > +
> > +set openssl_path=%WORKSPACE%
> > +
> > +popd
> > +
> > +goto :EOF
> > +
> > +:Help
> > +echo.
> > +echo Usage:
> > +echo GitEdk2.bat [-w Workspace_Directory] (optional) [-b Branch_Name]
> > (optional)
> > +echo.
> > +echo -w A absolute/relative path to be the workspace.
> > +echo Default value is the current directory.
> > +echo.
> > +echo -b The branch name of the repository. Currently, only master,
> udk2015,
> > +echo trunk (same as master) and bp13 (same as udk2015) are supported.
> > +echo Default value is master.
> > +echo.
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iBoardInitPostMemLib.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iBoardInitPostMemLib.inf
> > new file mode 100644
> > index 0000000000..542b53547f
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iBoardInitPostMemLib.inf
> > @@ -0,0 +1,36 @@
> > +## @file
> > +#
> > +# Copyright (c) 2018 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/Pe
> > iBoardInitPreMemLib.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iBoardInitPreMemLib.inf
> > new file mode 100644
> > index 0000000000..ab1286602b
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iBoardInitPreMemLib.inf
> > @@ -0,0 +1,38 @@
> > +## @file
> > +#
> > +# Copyright (c) 2018 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/SimicsOpenBoardPkg.dec
> > +
> > +[Sources]
> > + PeiX58ICH10Detect.c
> > + PeiX58ICH10InitPreMemLib.c
> > + PeiBoardInitPreMemLib.c
> > +
> > +[Pcd]
> > +
> > +[FixedPcd]
> > +
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iX58ICH10InitLib.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iX58ICH10InitLib.h
> > new file mode 100644
> > index 0000000000..996679e8f5
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/Library/BoardInitLib/Pe
> > iX58ICH10InitLib.h
> > @@ -0,0 +1,16 @@
> > +/** @file
> > + Copyright (c) 2018 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/PlatformPkgBuildOptio
> > n.dsc
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOptio
> > n.dsc
> > new file mode 100644
> > index 0000000000..8bce3c7a4f
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgBuildOptio
> > n.dsc
> > @@ -0,0 +1,89 @@
> > +## @file
> > +#
> > +# Copyright (c) 2018 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 CRB_EDKII_BUILD_OPTIONS = -D CRB_FLAG
> > + DEFINE EDKII_CPU_BUILD_OPTIONS = -D PURLEY_FLAG
> > + DEFINE TRAD_BUILD_OPTION = -D TRAD_FLAG=1
> > + DEFINE SUS_WELL_RESTORE_BUILD_OPTION = -D SUS_WELL_RESTORE=1
> > + DEFINE PCH_BUILD_OPTION = -D PCH_SERVER_BIOS_FLAG=1
> > + DEFINE SERVER_BUILD_OPTION = -D SERVER_BIOS_FLAG=1
> > + DEFINE PCH_PKG_OPTIONS = -D PCH_SPT
> > + DEFINE MAX_SOCKET_OPTIONS = -D MAX_SOCKET=2
> > +
> > + DEFINE EDKII_ALL_PPO_OPTIONS = $(EDKII_CPU_BUILD_OPTIONS)
> > + DEFINE PCH_BIOS_BUILD_OPTIONS = $(TRAD_BUILD_OPTION)
> > $(ULT_BUILD_OPTION) $(PCH_BUILD_OPTION)
> > $(SUS_WELL_RESTORE_BUILD_OPTION) $(SERVER_BUILD_OPTION)
> > + DEFINE EDKII_DSC_FEATURE_BUILD_OPTIONS =
> > $(CRB_EDKII_BUILD_OPTIONS) $(PCH_BIOS_BUILD_OPTIONS)
> > $(PCH_PKG_OPTIONS) $(EDKII_ALL_PPO_OPTIONS)
> > $(SPARING_SCRATCHPAD_OPTION)
> $(TRACE_HUB_DEBUG_BUILD_OPTIONS)
> > $(TRACE_HUB_INIT_BUILD_OPTIONS) $(MAX_SOCKET_OPTIONS) -D
> > EFI_PCI_IOV_SUPPORT -D WHEA_SUPPORT -D SKX_HOST -D CLX_HOST
> > +
> > +!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/PlatformPkgConfig.dsc
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
> > new file mode 100644
> > index 0000000000..f0ab846290
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgConfig.dsc
> > @@ -0,0 +1,56 @@
> > +## @file
> > +#
> > +# Copyright (c) 2018 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/PlatformPkgPcd.dsc
> > b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
> > new file mode 100644
> > index 0000000000..dc70adee34
> > --- /dev/null
> > +++
> > b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.dsc
> > @@ -0,0 +1,283 @@
> > +## @file
> > +#
> > +# Copyright (c) 2018 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.PcdResetOnMemoryTypeInformationChan
> > ge|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|0x17000
> > 00
> > +
> > + 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|0x200910
> > 13
> > +
> > + ## 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.PcdResetOnMemoryTypeInformationChan
> > ge|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
> > + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress|0xFFE00000
> > + gMinPlatformPkgTokenSpaceGuid.PcdFlashAreaSize|0x00200000
> > +
> > +[PcdsDynamicExDefault.common.DEFAULT]
> > +
> gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|30000
> > + gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress|0
> > +
> > +[PcdsDynamicExHii.common.DEFAULT]
> > +
> >
> gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobal
> > VariableGuid|0x0|50 # Variable: L"Timeout"
> > +
> >
> gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSuppo
> > rt"|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|0x204657303
> > 0363253
> > +
> > +[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|0x800
> > 0
> > + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xc000
> > +
> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0xc000
> > +
> >
> gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x200
> > 0
> > +
> >
> 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
> > +
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase|0x0
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize|0x0
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base|0x0
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size|0x0
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base|0x0
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size|0x800000000
> > +
> > +
> >
> gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType0StringBiosVersion|"Ve
> > r.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/SimicsX58Pkg.fdf.inc
> > b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58Pkg.fdf.inc
> > new file mode 100644
> > index 0000000000..f42e8b0e0e
> > --- /dev/null
> > +++
> > b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58Pkg.fdf.inc
> > @@ -0,0 +1,48 @@
> > +## @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 gSimicsX58PkgTokenSpaceGuid.PcdSimicsFdBaseAddress =
> > $(FW_BASE_ADDRESS)
> > +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareFdSize =
> $(FW_SIZE)
> > +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareBlockSize =
> > $(BLOCK_SIZE)
> > +
> > +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase =
> > $(FW_BASE_ADDRESS)
> > +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize =
> > 0xE000
> > +
> > +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase
> =
> > gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase +
> > gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> > +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize =
> > $(BLOCK_SIZE)
> > +
> > +SET
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase
> > = gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase +
> > gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize
> > +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> =
> > $(BLOCK_SIZE)
> > +
> > +SET gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase
> =
> > gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase +
> > gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> > +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize =
> > 0x10000
> > +
> > +DEFINE MEMFD_BASE_ADDRESS = 0x800000
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.
> > dsc
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.
> > dsc
> > new file mode 100644
> > index 0000000000..66ac16a940
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.
> > dsc
> > @@ -0,0 +1,244 @@
> > +## @file
> > +#
> > +# Copyright (c) 2018 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)/SimicsX58PkgIa32X64.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)/PlatformPkgConfig.dsc
> > + !include MinPlatformPkg/Include/Dsc/CoreCommonLib.dsc
> > + !include $(PCH_PKG)/PchCommonLib.dsc
> > +
> > +[LibraryClasses]
> > +
> >
> ReportFvLib|MinPlatformPkg/PlatformInit/Library/PeiReportFvLib/PeiReportFv
> > Lib.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/SerializeVari
> > ablesLib.inf
> > + LoadLinuxLib|$(BOARD_PKG)/Library/LoadLinuxLib/LoadLinuxLib.inf
> > +
> >
> CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/
> > CpuExceptionHandlerLibNull.inf
> > +
> > +
> >
> TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLibNull/TestPoi
> > ntCheckLibNull.inf
> > +
> >
> BoardInitLib|MinPlatformPkg/PlatformInit/Library/BoardInitLibNull/BoardInitLi
> > bNull.inf
> > +
> >
> SiliconPolicyInitLib|$(BOARD_PKG)/Policy/Library/SiliconPolicyInitLib/SiliconPol
> > icyInitLib.inf
> > +
> >
> SiliconPolicyUpdateLib|$(BOARD_PKG)/Policy/Library/SiliconPolicyUpdateLib/S
> > iliconPolicyUpdateLib.inf
> > +
> >
> PciSegmentInfoLib|MinPlatformPkg/Pci/Library/PciSegmentInfoLibSimple/PciS
> > egmentInfoLibSimple.inf
> > +
> > + !include MinPlatformPkg/Include/Dsc/CorePeiLib.dsc
> > +
> > +
> >
> S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScri
> > ptLib.inf
> > +
> >
> AslUpdateLib|MinPlatformPkg/Acpi/Library/DxeAslUpdateLib/DxeAslUpdateLib.
> > inf
> > +[LibraryClasses.common.SEC]
> > +
> >
> ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExt
> > ractGuidedSectionLib.inf
> > +
> > +[LibraryClasses.common.PEI_CORE]
> > +
> > +[LibraryClasses.common.PEIM]
> > +
> >
> PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiReso
> > urcePublicationLib.inf
> > + MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
> > +
> > +[LibraryClasses.IA32]
> > +!if $(TARGET) == DEBUG
> > +
> >
> TestPointCheckLib|MinPlatformPkg/Test/Library/TestPointCheckLib/PeiTestPoi
> > ntCheckLib.inf
> > +!endif
> > + TestPointLib|MinPlatformPkg/Test/Library/TestPointLib/PeiTestPointLib.inf
> > +
> > + !include MinPlatformPkg/Include/Dsc/CoreDxeLib.dsc
> > +
> > +[LibraryClasses.common.DXE_CORE]
> > +
> > +[LibraryClasses.common.DXE_RUNTIME_DRIVER]
> > +
> >
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> > Ich10.inf
> > +
> > +[LibraryClasses.common.UEFI_DRIVER]
> > +
> >
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> > Ich10.inf
> > +
> > +[LibraryClasses.common.DXE_DRIVER]
> > +
> >
> PlatformBootManagerLib|$(BOARD_PKG)/Overrides/MdeModulePkg/Library/P
> > latformBootManagerLib/PlatformBootManagerLib.inf
> > +
> >
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> > Ich10.inf
> > +
> > +[LibraryClasses.common.UEFI_APPLICATION]
> > +
> >
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> > Ich10.inf
> > +
> > +[LibraryClasses.common.DXE_SMM_DRIVER]
> > +
> >
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> > Ich10.inf
> > +
> >
> SpiFlashCommonLib|$(PCH_PKG)/Library/SmmSpiFlashCommonLib/SmmSpiFla
> > shCommonLib.inf
> > +
> > +[LibraryClasses.common.SMM_CORE]
> > +
> >
> PciLib|$(BOARD_PKG)/Overrides/MdePkg/Library/BasePciLibCf8/DxePciLibX58
> > Ich10.inf
> > +
> > + !include $(BOARD_PKG)/$(BOARD_NAME)/PlatformPkgPcd.dsc
> > +
> > +[Components.IA32]
> > + !include $(SKT_PKG)/SktPei.dsc
> > + !include MinPlatformPkg/Include/Dsc/CorePeiInclude.dsc
> > +
> > + $(BOARD_PKG)/PlatformPei/PlatformPei.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/PeiBoardI
> > nitPreMemLib.inf
> > + }
> > + MinPlatformPkg/PlatformInit/PlatformInitPei/PlatformInitPostMem.inf {
> > + <LibraryClasses>
> > +
> >
> BoardInitLib|$(BOARD_PKG)/$(BOARD_NAME)/Library/BoardInitLib/PeiBoardI
> > nitPostMemLib.inf
> > + }
> > + MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPreMem.inf
> > + MinPlatformPkg/PlatformInit/SiliconPolicyPei/SiliconPolicyPeiPostMem.inf
> > +
> > +[Components.X64]
> > + !include MinPlatformPkg/Include/Dsc/CoreDxeInclude.dsc
> > +
> >
> $(BOARD_PKG)/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.i
> > nf
> > + !include AdvancedFeaturePkg/Include/Dsc/CoreAdvancedDxeInclude.dsc
> > +
> > + MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
> > + $(BOARD_PKG)/Overrides/MdeModulePkg/Logo/LogoDxe.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)/PlatformDxe/Platform.inf
> > + MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
> > +
> >
> MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.
> > inf
> > +
> > + #
> > + # Shell
> > + #
> > + ShellPkg/Application/Shell/Shell.inf {
> > + <PcdsFixedAtBuild>
> > + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> > + <LibraryClasses>
> > +
> >
> NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2Command
> > sLib.inf
> > +
> >
> NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1Command
> > sLib.inf
> > +
> >
> NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3Command
> > sLib.inf
> > +
> >
> NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1Comma
> > ndsLib.inf
> > +
> >
> NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1Comman
> > dsLib.inf
> > +
> >
> NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1Comma
> > ndsLib.inf
> > +
> >
> NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1Co
> > mmandsLib.inf
> > +
> >
> NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2Co
> > mmandsLib.inf
> > +
> >
> ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLi
> > b.inf
> > +
> >
> HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.
> > inf
> > +
> >
> BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCo
> > mmandLib.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)/Overrides/MdeModulePkg/Library/PciHostBr
> > idgeLib/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)/PlatformPkgBuildOption.dsc
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.f
> > df
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.f
> > df
> > new file mode 100644
> > index 0000000000..d6c381a515
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/SimicsX58PkgIa32X64.f
> > df
> > @@ -0,0 +1,303 @@
> > +## @file
> > +#
> > +# Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +!include SimicsX58Pkg.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|gEfi
> > MdeModulePkgTokenSpaceGuid.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|gEfiMd
> > eModulePkgTokenSpaceGuid.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
> >
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase|gSimicsX58PkgT
> > okenSpaceGuid.PcdSimicsSecPageTablesSize
> > +
> > +0x006000|0x001000
> >
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase|gSimicsX58Pkg
> > TokenSpaceGuid.PcdSimicsLockBoxStorageSize
> > +
> > +0x007000|0x001000
> >
> +gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gSimicsX
> > 58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> > +
> > +0x010000|0x008000
> >
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|gSimicsX58Pk
> > gTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> > +
> > +0x020000|0x0E0000
> >
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase|gSimicsX58PkgToke
> > nSpaceGuid.PcdSimicsPeiMemFvSize
> > +FV = FvPreMemory
> > +
> > +0x100000|0xA00000
> >
> +gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase|gSimicsX58PkgTok
> > enSpaceGuid.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
> > +
> > +!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)/PchPreMemoryInclude.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)/PlatformPei/PlatformPei.inf
> > +!include $(SKT_PKG)/SktPostMemoryInclude.fdf
> > +!include $(PCH_PKG)/PchPostMemoryInclude.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
> > +INF
> >
> $(BOARD_PKG)/Overrides/PcAtChipsetPkg/8259InterruptControllerDxe/8259.i
> > nf
> > +!include $(SKT_PKG)/SktUefiBootInclude.fdf
> > +!include $(PCH_PKG)/PchUefiBootInclude.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 $(BOARD_PKG)/Overrides/MdeModulePkg/Logo/LogoDxe.inf
> > +INF MinPlatformPkg/PlatformInit/PlatformInitDxe/PlatformInitDxe.inf
> > +INF MinPlatformPkg/PlatformInit/PlatformInitSmm/PlatformInitSmm.inf
> > +INF $(BOARD_PKG)/PlatformDxe/Platform.inf
> > +
> > +INF ShellPkg/Application/Shell/Shell.inf
> > +
> > +#
> > +# Network modules
> > +#
> > +FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 {
> > + SECTION PE32 = SimicsICH10SiliconBinPkg/UndiBinary/GigUndiDxe.efi
> > + SECTION UI = "IntelIch10UNDI"
> > +}
> > +!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/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|gEfiMde
> > ModulePkgTokenSpaceGuid.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/bld.bat
> > b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
> > new file mode 100644
> > index 0000000000..efce310dfe
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/bld.bat
> > @@ -0,0 +1,139 @@
> > +@echo off
> > +@REM @file
> > +@REM Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> > +@REM
> > +@REM SPDX-License-Identifier: BSD-2-Clause-Patent
> > +@REM
> > +
> > +@echo off
> > +
> > +REM Run setlocal to take a snapshot of the environment variables. endlocal
> is
> > called to restore the environment.
> > +setlocal
> > +set SCRIPT_ERROR=0
> > +
> > +REM ---- Do NOT use :: for comments Inside of code blocks() ----
> > +
> >
> +::***********************************************************
> > ***********
> > +:: Initial Setup
> >
> +::***********************************************************
> > ***********
> > +
> > +:parseCmdLine
> > +if "%1"=="" goto :argumentCheck
> > +
> > +if /I "%1"=="debug" set TARGET=DEBUG
> > +if /I "%1"=="release" set TARGET=RELEASE
> > +
> > +if /I "%1"=="cleantree" (
> > + set BUILD_TYPE=cleantree
> > + call :cleantree
> > + goto :EOF
> > +)
> > +
> > +shift
> > +GOTO :parseCmdLine
> > +
> > +:argumentCheck:
> > +
> > +if /I "%TARGET%" == "" (
> > + echo Info: debug/release argument is empty, use DEBUG as default
> > + set TARGET=DEBUG
> > +)
> > +
> > +REM Art to notify which board you're working on
> > +echo.
> > +type logo.txt
> > +echo.
> > +
> > +::
> > +:: Build configuration
> > +::
> > +set BUILD_REPORT_FLAGS=
> > +set BUILD_CMD_LINE=
> > +set BUILD_LOG=%WORKSPACE%\Build\BuildSrc\build.log
> > +set BUILD_REPORT=%WORKSPACE%\Build\BuildSrc\BuildReport.txt
> > +
> > +del %BUILD_LOG% *.efi *.log 2>NUL
> > +
> > +echo -------------------------------------------------------------------------------------------
> -
> > +echo.
> > +echo QSP Build Start
> > +echo.
> > +echo -------------------------------------------------------------------------------------------
> -
> > +
> > +
> > +:doPreBuild
> > +echo.
> > +echo --------------------------------------------------------------------
> > +echo.
> > +echo Prebuild Start
> > +echo.
> > +echo --------------------------------------------------------------------
> > +call prebuild.bat
> > +if %SCRIPT_ERROR% NEQ 0 EXIT /b %ERRORLEVEL%
> > +
> > +echo --------------------------------------------------------------------
> > +echo.
> > +echo Prebuild End
> > +echo.
> > +echo --------------------------------------------------------------------
> > +if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
> > +timeout 1
> > +
> > +:buildBios
> > +set BUILD_CMD_LINE=%BUILD_CMD_LINE% -D
> > MAX_SOCKET=%MAX_SOCKET% -y %BUILD_REPORT%
> > +echo --------------------------------------------------------------------
> > +echo.
> > +echo Build Start
> > +echo.
> > +echo --------------------------------------------------------------------
> > +echo.
> > +echo build %BUILD_CMD_LINE% --log=%BUILD_LOG%
> > %BUILD_REPORT_FLAGS%
> > +call build %BUILD_CMD_LINE% --log=%BUILD_LOG%
> > %BUILD_REPORT_FLAGS%
> > +echo --------------------------------------------------------------------
> > +echo.
> > +echo Build End
> > +echo.
> > +echo --------------------------------------------------------------------
> > +if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
> > +timeout 1
> > +
> > +:postBuild
> > +
> > +echo --------------------------------------------------------------------
> > +echo.
> > +echo PostBuild Start
> > +echo.
> > +echo --------------------------------------------------------------------
> > +echo.
> > +REM call postbuild.bat
> > +if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
> > +timeout 1
> > +echo --------------------------------------------------------------------
> > +echo.
> > +echo PostBuild End
> > +echo.
> > +echo --------------------------------------------------------------------
> > +
> > +echo %date% %time%
> > +echo.
> > +
> > +echo -------------------------------------------------------------------------------------------
> -
> > +echo.
> > +echo QSP Build End
> > +echo.
> > +echo -------------------------------------------------------------------------------------------
> -
> > +
> > +:done
> > +endlocal & EXIT /b %SCRIPT_ERROR%
> > +
> > +::--------------------------------------------------------
> > +::-- Function section starts below here
> > +::--------------------------------------------------------
> > +:cleantree
> > +choice /t 3 /d y /m "Confirm: clean tree of intermediate files created in tree
> > during build"
> > +if %ERRORLEVEL% EQU 2 goto :EOF
> > +goto :EOF
> > +
> > +
> > +:ErrorHandler:
> > +echo Error handler
> > diff --git
> > a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
> > b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
> > new file mode 100644
> > index 0000000000..ad3ae229e8
> > --- /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 = WORKSPACE_PLATFORM_BIN
> > +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/SimicsX58PkgIa32X64.dsc
> > +BOARD_PKG_PCD_DSC =
> > SimicsOpenBoardPkg/BoardX58ICH10/PlatformPkgPcd.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
> > diff --git a/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
> > b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
> > new file mode 100644
> > index 0000000000..666332e2d4
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/BoardX58ICH10/prebuild.bat
> > @@ -0,0 +1,198 @@
> > +@echo off
> > +@REM @file
> > +@REM Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> > +@REM
> > +@REM SPDX-License-Identifier: BSD-2-Clause-Patent
> > +@REM
> > +
> > +@set SCRIPT_ERROR=0
> > +
> > +set /a prebuildstep=0
> > +
> > +call :check_BuildTools
> > +if %SCRIPT_ERROR% NEQ 0 GOTO :done
> > +
> > +call :setBuildEnv
> > +if %SCRIPT_ERROR% NEQ 0 GOTO :done
> > +
> > +call :createTargetTxt
> > +if %SCRIPT_ERROR% NEQ 0 GOTO :done
> > +
> > +REM call :genPlatformOffsetHeaderFile
> > +REM if %SCRIPT_ERROR% NEQ 0 GOTO :done
> > +
> > +:prebuildFinish
> > +echo.
> > +echo ACTIVE_PLATFORM = %WORKSPACE%\edk2-
> >
> platforms\Platform\Intel\%BOARD_PKG%\%BOARD_NAME%\SimicsX58PkgIa3
> > 2X64.dsc
> > +echo EDK_TOOLS_PATH = %EDK_TOOLS_PATH%
> > +echo TARGET = %TARGET%
> > +echo TARGET_ARCH = IA32 X64
> > +echo TOOL_CHAIN_TAG = %TOOL_CHAIN_TAG%
> > +echo WORKSPACE = %WORKSPACE%
> > +echo PACKAGES_PATH = %PACKAGES_PATH%
> > +echo MAX_CONCURRENT_THREAD_NUMBER =
> > %BUILD_MAX_CON_THREAD_NUM%
> > +echo.
> > +echo Build Path = %OUTPUT_DIR%
> > +echo.
> > +
> > +REM Remove environment variable because it's no longer needed.
> > +set BUILD_MAX_CON_THREAD_NUM=
> > +
> > +:done
> > +REM Use done label to exit batch file and run any final steps; GOTO :EOF
> > immediately exits.
> > +EXIT /B %SCRIPT_ERROR%
> > +
> > +::--------------------------------------------------------
> > +::-- Function section starts below here
> > +::--------------------------------------------------------
> > +
> > +:cleanup_check_VSTools
> > +set COMPILER_VERSION_STRING=
> > +del cloutput.txt > nul
> > +REM cleanup_check_VSTools is called below. When a label is called, 'GOTO
> > :EOF' is used to return to caller.
> > +GOTO :EOF
> > +
> > +:check_BuildTools
> > +echo PreBuild.%prebuildstep% check_BuildTools
> > +echo ..VSTools
> > +set /a prebuildstep=%prebuildstep%+1
> > +set TOOL_CHAIN_TAG=
> > +@if not defined TOOL_CHAIN_TAG (
> > + echo.
> > + echo Prebuild: TOOL_CHAIN_TAG is not set before
> > + echo.
> > +
> > + @if defined VS140COMNTOOLS (
> > + echo.
> > + echo Set the VS2015 environment.
> > + echo.
> > + set CL_SEL=VS2015
> > + if /I "%VS140COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio
> > 14.0\Common7\Tools\" (
> > + set TOOL_CHAIN_TAG=VS2015
> > + ) else (
> > + set TOOL_CHAIN_TAG=VS2015x86
> > + )
> > + if /I "%PROCESSOR_ARCHITECTURE%" == "AMD64" (
> > + set CL_CMDLINE="%VS140COMNTOOLS:~0,-14%VC\bin\amd64\cl.exe"
> > + ) else (
> > + set CL_CMDLINE="%VS140COMNTOOLS:~0,-14%VC\bin\cl.exe"
> > + )
> > + ) else if defined VS120COMNTOOLS (
> > + echo.
> > + echo Set the VS2013 environment.
> > + echo.
> > + set CL_SEL=VS2013
> > + if /I "%VS120COMNTOOLS%" == "C:\Program Files\Microsoft Visual Studio
> > 12.0\Common7\Tools\" (
> > + set TOOL_CHAIN_TAG=VS2013
> > + ) else (
> > + set TOOL_CHAIN_TAG=VS2013x86
> > + )
> > + if /I "%PROCESSOR_ARCHITECTURE%" == "AMD64" (
> > + set CL_CMDLINE="%VS120COMNTOOLS:~0,-14%VC\bin\amd64\cl.exe"
> > + ) else (
> > + set CL_CMDLINE="%VS120COMNTOOLS:~0,-14%VC\bin\cl.exe"
> > + )
> > + ) else (
> > + echo.
> > + echo !!! ERROR !!! VS2015 or VS2013 not installed correctly. !!!
> > + echo.
> > + goto :ErrorExit
> > + )
> > +)
> > +
> > +echo ..iASL
> > +set CHECK_PATH_IASL=%IASL_PREFIX%
> > +if not exist %CHECK_PATH_IASL%\iasl.exe (
> > + echo.
> > + echo !!! ERROR !!! Could not find iASL compiler at
> > %CHECK_PATH_IASL%\iasl.exe. !!!
> > + echo.
> > + set SCRIPT_ERROR=1
> > +)
> > +set CHECK_PATH_IASL=
> > +
> > +echo ..NASM
> > +set CHECK_PATH_NASM=c:\NASM
> > +if not exist %CHECK_PATH_NASM%\nasm.exe (
> > + echo.
> > + echo !!! ERROR !!! Could not find NASM compiler at
> > %CHECK_PATH_NASM%\nasm.exe. !!!
> > + echo.
> > + set SCRIPT_ERROR=1
> > +)
> > +set CHECK_PATH_NASM=
> > +
> > +echo ..Python
> > +set CHECK_PATH_PYTHON=c:\Python27
> > +if not exist %CHECK_PATH_PYTHON%\python.exe (
> > + echo.
> > + echo !!! ERROR !!! Could not find Python at
> > %CHECK_PATH_PYTHON%\python.exe. !!!
> > + echo.
> > + set SCRIPT_ERROR=1
> > +)
> > +set CHECK_PATH_PYTHON=
> > +set PYTHON_HOME=C:\Python27
> > +
> > +GOTO :EOF
> > +
> > +:setBuildEnv
> > +echo PreBuild.%prebuildstep% SetBuildEnv
> > +set /a prebuildstep=%prebuildstep%+1
> > +
> > +@set BOARD_PKG=SimicsOpenBoardPkg
> > +@set BOARD_NAME=BoardX58ICH10
> > +@set MAX_SOCKET=2
> > +
> > +echo.
> > +echo BOARD_NAME=%BOARD_NAME%
> > +echo BOARD_PKG=%BOARD_PKG%
> > +echo MAX_SOCKET=%MAX_SOCKET%
> > +echo TARGET=%TARGET%
> > +
> > +@set
> >
> OUTPUT_DIR=%WORKSPACE%\Build\BuildSrc\%BOARD_PKG%\%BOARD_NAM
> > E%\%TARGET%_%TOOL_CHAIN_TAG%
> > +
> > +if not exist %OUTPUT_DIR% mkdir %OUTPUT_DIR%
> > +GOTO :EOF
> > +
> > +:createTargetTxt
> > +echo PreBuild.%prebuildstep% CreateTargetTxt
> > +set /a prebuildstep=%prebuildstep%+1
> > +set /a BUILD_MAX_CON_THREAD_NUM = %NUMBER_OF_PROCESSORS%-1
> > +@REM set /a BUILD_MAX_CON_THREAD_NUM = 1
> > +findstr /V "ACTIVE_PLATFORM TARGET TARGET_ARCH TOOL_CHAIN_TAG
> > BUILD_RULE_CONF MAX_CONCURRENT_THREAD_NUMBER"
> > %WORKSPACE%\Conf\target.txt > %OUTPUT_DIR%\target.txt 2>NUL
> > +echo ACTIVE_PLATFORM = %WORKSPACE%/edk2-
> >
> platforms/Platform/Intel/%BOARD_PKG%/%BOARD_NAME%/SimicsX58PkgIa3
> > 2X64.dsc >> %OUTPUT_DIR%\target.txt
> > +echo TARGET = %TARGET% >>
> > %OUTPUT_DIR%\target.txt
> > +echo TARGET_ARCH = IA32 X64 >>
> > %OUTPUT_DIR%\target.txt
> > +echo TOOL_CHAIN_TAG = %TOOL_CHAIN_TAG% >>
> > %OUTPUT_DIR%\target.txt
> > +echo BUILD_RULE_CONF = Conf/build_rule.txt >>
> > %OUTPUT_DIR%\target.txt
> > +echo MAX_CONCURRENT_THREAD_NUMBER =
> > %BUILD_MAX_CON_THREAD_NUM% >> %OUTPUT_DIR%\target.txt
> > +if exist %WORKSPACE%\Conf\target.txt (
> > + del /f %WORKSPACE%\Conf\target.txt
> > +)
> > +move /Y %OUTPUT_DIR%\target.txt %WORKSPACE%\Conf\ > nul
> > +if not exist %OUTPUT_DIR%\X64 mkdir %OUTPUT_DIR%\X64
> > +GOTO :EOF
> > +
> > +
> > +:genPlatformOffsetHeaderFile
> > +echo.
> > +echo PreBuild.%prebuildstep% GenPlatformOffsetHeaderFile
> > +set /a prebuildstep=%prebuildstep%+1
> > +
> > +echo Info: re-generating PlatformOffset header files
> > +
> > +set PRE_BUILD_CMD_LINE=%BUILD_CMD_LINE% -D
> > MAX_SOCKET=%MAX_SOCKET%
> > +set PRE_BUILD_LOG=%WORKSPACE%\Build\BuildSrc\prebuild.log
> > +set PRE_BUILD_REPORT=%WORKSPACE%\Build\BuildSrc\preBuildReport.txt
> > +
> > +echo build %PRE_BUILD_CMD_LINE% -m
> > %BOARD_PKG%\Acpi\BoardAcpiDxe\Dsdt.inf -y %PRE_BUILD_REPORT% --
> > log=%PRE_BUILD_LOG%
> > +call build %PRE_BUILD_CMD_LINE% -m
> > %BOARD_PKG%\Acpi\BoardAcpiDxe\Dsdt.inf -y %PRE_BUILD_REPORT% --
> > log=%PRE_BUILD_LOG%
> > +if %ERRORLEVEL% NEQ 0 EXIT /b %ERRORLEVEL%
> > +
> > +@REM PSYS == FIX0
> > +@REM MCTL == FIX8
> > +set AML_FILTER="\"PSYS\" .MCTL\" .FIX[0-9,A-Z]\""
> > +echo AML_FILTER=%AML_FILTER%
> > +%WORKSPACE%\edk2-
> >
> platforms\Platform\Intel\MinPlatformPkg\Tools\AmlGenOffset\AmlGenOffset.
> > py -d --aml_filter %AML_FILTER% -o %WORKSPACE%\edk2-
> >
> platforms\Platform\Intel\%BOARD_PKG%\Acpi\BoardAcpiDxe\AmlOffsetTable.
> > c
> >
> %OUTPUT_DIR%\X64\PurleyOpenBoardPkg\Acpi\BoardAcpiDxe\DSDT\OUTPU
> > T\Dsdt\WFPPlatform.offset.h
> > +echo.
> > +echo GenOffset done
> > +
> > +GOTO :EOF
> > --
> > 2.16.2.windows.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform
2019-08-23 17:06 ` David Wei
@ 2019-08-26 23:00 ` Kubacki, Michael A
0 siblings, 0 replies; 37+ messages in thread
From: Kubacki, Michael A @ 2019-08-26 23:00 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
Thanks David. No more comments for this patch.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 23, 2019 10:06 AM
> To: Kubacki, Michael A <michael.a.kubacki@intel.com>;
> 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>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 7/7] Platform/Intel: Add build option for
> SIMICS QSP Platform
>
> Hi Mike,
> Please see the updates online below. Please let me know if you have any
> more comments.
>
> Thanks
> David
>
> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Monday, August 19, 2019 6:05 PM
> To: Wei, David Y <david.y.wei@intel.com>; 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>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 7/7] Platform/Intel: Add build option for
> SIMICS QSP Platform
>
> You will need to resolve a conflict in build.cfg. When you do so, please keep
> the boards under [PLATFORMS] in lexicographically ascending order for ease
> of maintenance.
> Ydwei: done
> > -----Original Message-----
> > From: Wei, David Y
> > Sent: Friday, August 9, 2019 3:47 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-platform patch 7/7] Platform/Intel: Add build option
> > for SIMICS QSP Platform
> >
> > Add build option in build script for SIMICS QSP Platform
> >
> > 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>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> >
> > Signed-off-by: David Wei <david.y.wei@intel.com>
> > ---
> > Platform/Intel/build.cfg | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/Platform/Intel/build.cfg b/Platform/Intel/build.cfg index
> > fc6e4fe824..2ebe09a632 100644
> > --- a/Platform/Intel/build.cfg
> > +++ b/Platform/Intel/build.cfg
> > @@ -54,3 +54,5 @@ NUMBER_OF_PROCESSORS = 0
> > KabylakeRvp3 = KabylakeOpenBoardPkg/KabylakeRvp3/build_config.cfg
> > N1xxWU = ClevoOpenBoardPkg/N1xxWU/build_config.cfg
> > BoardMtOlympus =
> PurleyOpenBoardPkg/BoardMtOlympus/build_config.cfg
> > +WhiskeylakeURvp =
> > +WhiskeylakeOpenBoardPkg/WhiskeylakeURvp/build_config.cfg
> > +BoardX58ICH10 = SimicsOpenBoardPkg/BoardX58ICH10/build_config.cfg
> > --
> > 2.16.2.windows.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules
2019-08-23 16:57 ` David Wei
@ 2019-08-26 23:13 ` Kubacki, Michael A
0 siblings, 0 replies; 37+ messages in thread
From: Kubacki, Michael A @ 2019-08-26 23:13 UTC (permalink / raw)
To: Wei, David Y, devel@edk2.groups.io
Cc: Wu, Hao A, Gao, Liming, Sinha, Ankit, Agyeman, Prince,
Desimone, Nathaniel L, Kinney, Michael D
> 11. LoadLinuxLib.inf: Library name does not following naming convention. I.e.
> should be BaseLoadLinuxLib.inf.
> Ydwei: This driver is from edk2\OvmfPkg\Library\LoadLinuxLib. I didn't make
> change.
makubacki: While SimicsOpenBoardPkg has an instance of the library, it should follow the naming convention expected in the package. You do not need to change the OvmfPkg instance but please update this instance.
> 12. LoadLinuxLib.inf: This is not truly a BASE library. For example, gBS (boot
> services) are unavailable in Runtime DXE.
> Ydwei: This driver is from edk2\OvmfPkg\Library\LoadLinuxLib. I think it is just
> used by Linux Loader.
makubacki: Can the library just have type DXE_DRIVER then?
> 15. Cmos.c: It seems CmosAccessLib in BoardModulePkg could be used here to
> avoid duplication.
> Ydwei: I tried CmosAccessLib in BoardModulePkg and it cause build error. I
> didn't make change.
makubacki: I'll file a BZ to investigate and consolidate this in the future.
> 16. Fv.c: In MinPlatform, a more intuitive place to manage FVs is in a board-
> specific instance of PeiReportFvLib
> Ydwei: It is used for SIMICS S3 resume. Different purpose.
makubacki: Boot mode can be read in S3 resume. See:
https://github.com/tianocore/edk2-platforms/blob/master/Platform/Intel/MinPlatformPkg/PlatformInit/Library/PeiReportFvLib/PeiReportFvLib.c
ReportFvPei in MinPlatformPkg links against a ReportFvLib library class to allow custom FV installation behavior. In this case, it seems the SimicsOpenBoardPkg ReportFvLib library instance just needs to perform the logic currently in PeiFvInitialization ().
> 17. General comment: The modules "PlatformPei" and "PlatformDxe" should be
> avoided in a MinPlatform.
> MinPlatformPkg is considered the "platform" and SimicsOpenBoardPkg is
> considered the "board", therefore this
> code should likely be in a board library linked against a PlatformInit module
> in MinPlatformPkg. Such as BoardInitLib
> which is very empty at the moment. At a minimum, if kept as a module for
> dispatch, the name should not lead to confusion
> with platform modules in MinPlatformPkg.
> Ydwei: They are SIMICS specifical. So I change their name as SimicsPei and
> SimicsDxe
makubacki: The name change is good to reduce confusion. But the code should be moved to the BoardInitLib behind the proper board APIs. One of the goals of the Minimum Platform is for code to be in predictable locations with a consistent boot flow. If the code is not moved now, a BZ will need to be filed so the code can be moved to the appropriate locations in a follow up change.
> -----Original Message-----
> From: Wei, David Y
> Sent: Friday, August 23, 2019 9:58 AM
> To: Kubacki, Michael A <michael.a.kubacki@intel.com>; 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>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add
> SimicsOpenBoardPkg and its modules
>
> Hi Mike,
> Please see the updates online below. Please let me know if you have any more
> comments.
>
> Thanks
> David
>
> -----Original Message-----
> From: Kubacki, Michael A
> Sent: Monday, August 19, 2019 6:04 PM
> To: Wei, David Y <david.y.wei@intel.com>; 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>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>
> Subject: RE: [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add
> SimicsOpenBoardPkg and its modules
>
> Feedback I could not find already covered elsewhere:
>
> 1. Dsdt.asl: Change "OVMF" in the following line to something else unique to this
> implementation:
> "DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF ", 4) {"
> Ydwei: done
> 2. BasePchSpiCommonLib.inf: This silicon package should not have a
> dependency on SimicsOpenBoardPkg.dec.
> Ydwei: done
> 3. Platform.h: This header guard definition is unusual in style and convention,
> please correct: "_Platform_h_INCLUDED_"
> Ydwei: done
> 4. Platform.h: Please update usage of "OVMF" in various signatures throughout
> the file to something package unique.
> Ydwei: done
> 5. SimicsX58PlatformConfig.h: Why is this file not in SimicsX58SktPkg?
> Ydwei: done
> 6. SimicsX58PlatformConfig.h: Change "OVMF" in copyright header to "Simics
> X58"
> Ydwei: done
> 7. SimicsPlatforms.h: Change "OVMF" in copyright header to "Simics"
> Ydwei: done
> 8. SimicsPlatforms.h - Line 16: Follow up on TODO
> Ydwei: done
> 9. X58Ich10.h: Why is this file in the Simics board package? It should be in the
> silicon package.
> Ydwei: done
> 10. LoadLinuxLib.inf: This package should avoid a depdency on OvmfPkg.dec
> Ydwei: done
> 11. LoadLinuxLib.inf: Library name does not following naming convention. I.e.
> should be BaseLoadLinuxLib.inf.
> Ydwei: This driver is from edk2\OvmfPkg\Library\LoadLinuxLib. I didn't make
> change.
> 12. LoadLinuxLib.inf: This is not truly a BASE library. For example, gBS (boot
> services) are unavailable in Runtime DXE.
> Ydwei: This driver is from edk2\OvmfPkg\Library\LoadLinuxLib. I think it is just
> used by Linux Loader.
> 13. Platform.c: Change "OVMF" reference in copyright header.
> Ydwei: done
> 14. Platform.h: Change "OVMF" reference in copyright header.
> Ydwei: done
> 15. Cmos.c: It seems CmosAccessLib in BoardModulePkg could be used here to
> avoid duplication.
> Ydwei: I tried CmosAccessLib in BoardModulePkg and it cause build error. I
> didn't make change.
> 16. Fv.c: In MinPlatform, a more intuitive place to manage FVs is in a board-
> specific instance of PeiReportFvLib
> Ydwei: It is used for SIMICS S3 resume. Different purpose.
> 17. General comment: The modules "PlatformPei" and "PlatformDxe" should be
> avoided in a MinPlatform.
> MinPlatformPkg is considered the "platform" and SimicsOpenBoardPkg is
> considered the "board", therefore this
> code should likely be in a board library linked against a PlatformInit module
> in MinPlatformPkg. Such as BoardInitLib
> which is very empty at the moment. At a minimum, if kept as a module for
> dispatch, the name should not lead to confusion
> with platform modules in MinPlatformPkg.
> Ydwei: They are SIMICS specifical. So I change their name as SimicsPei and
> SimicsDxe
> 18. PlatformPei.inf: This package should avoid a depdency on OvmfPkg.dec
> Ydwei: done
> 19. X58SmamSaveStateMap.h: If X58-specific, it should go to SimicsX58SktPkg.
> Ydwei: done
> 20. SerializeVariablesLib.inf: This package should avoid a depdency on
> OvmfPkg.dec
> Ydwei: done
> 21. SimicsOpenBoardPkg.dec: Pcds in the gSimicsX58PkgTokenSpaceGuid token
> space should be declared in a DEC file
> in the SimicsX58SktPkg. SimicsOpenBoardPkg should not be hardcoded to
> this particular silicon design.
> Ydwei: done
> 22. SimicsOpenBoardPkg.dec: "X58" should be removed from the copyright
> header as the DEC is at the package-level
> and not the board level.
> Ydwei: done
> 23. SimicsOpenBoardPkg.dec: The PACKAGE_NAME should not be "
> SimicsX58Pkg" as the DEC is at package-level and
> not Simics board-specific.
> Ydwei: done
> > -----Original Message-----
> > From: Wei, David Y
> > Sent: Friday, August 9, 2019 3:47 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-platform patch 3/7] SimicsOpenBoardPkg: Add
> > SimicsOpenBoardPkg and its modules
> >
> > Add modules AcpiTables, Include, Library, PlatformDxe, PlatformPei, Policy,
> > SmbiosPlatformDxe
> > 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>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> >
> > Signed-off-by: David Wei <david.y.wei@intel.com>
> > ---
> > .../Library/LoadLinuxLib/Linux.c | 662 ++++++++++++++++
> > .../Library/LoadLinuxLib/LinuxGdt.c | 175 +++++
> > .../Library/NvVarsFileLib/FsAccess.c | 507 ++++++++++++
> > .../Library/NvVarsFileLib/NvVarsFileLib.c | 77 ++
> > .../SerializeVariablesLib/SerializeVariablesLib.c | 869
> > +++++++++++++++++++++
> > .../SimicsOpenBoardPkg/PlatformDxe/Platform.c | 865
> > ++++++++++++++++++++
> > .../PlatformDxe/PlatformConfig.c | 123 +++
> > .../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c | 57 ++
> > .../PlatformPei/FeatureControl.c | 114 +++
> > Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c | 100 +++
> > .../SimicsOpenBoardPkg/PlatformPei/MemDetect.c | 568
> ++++++++++++++
> > .../SimicsOpenBoardPkg/PlatformPei/Platform.c | 631 +++++++++++++++
> > .../SiliconPolicyInitLib/SiliconPolicyInitLib.c | 108 +++
> > .../SiliconPolicyUpdateLib.c | 70 ++
> > .../SmbiosPlatformDxe/SmbiosPlatformDxe.c | 148 ++++
> > .../SimicsOpenBoardPkg/AcpiTables/AcpiTables.inf | 31 +
> > .../Intel/SimicsOpenBoardPkg/AcpiTables/Dsdt.asl | 821
> > +++++++++++++++++++
> > .../Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h | 75 ++
> > .../Include/Guid/SimicsX58PlatformConfig.h | 17 +
> > .../Include/IndustryStandard/X58Ich10.h | 106 +++
> > .../SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h | 298 +++++++
> > .../SimicsOpenBoardPkg/Include/Protocol/IsaIo.h | 356 +++++++++
> > .../Include/Protocol/Legacy8259.h | 291 +++++++
> > .../Include/Register/X58SmramSaveStateMap.h | 178 +++++
> > .../SimicsOpenBoardPkg/Include/SimicsPlatforms.h | 54 ++
> > .../Library/LoadLinuxLib/Ia32/JumpToKernel.nasm | 41 +
> > .../Library/LoadLinuxLib/LoadLinuxLib.h | 52 ++
> > .../Library/LoadLinuxLib/LoadLinuxLib.inf | 42 +
> > .../Library/LoadLinuxLib/X64/JumpToKernel.nasm | 85 ++
> > .../Library/NvVarsFileLib/NvVarsFileLib.h | 55 ++
> > .../Library/NvVarsFileLib/NvVarsFileLib.inf | 53 ++
> > .../SerializeVariablesLib/SerializeVariablesLib.h | 33 +
> > .../SerializeVariablesLib.inf | 36 +
> > .../SimicsOpenBoardPkg/PlatformDxe/Platform.h | 37 +
> > .../SimicsOpenBoardPkg/PlatformDxe/Platform.inf | 65 ++
> > .../SimicsOpenBoardPkg/PlatformDxe/Platform.uni | 31 +
> > .../PlatformDxe/PlatformConfig.h | 51 ++
> > .../PlatformDxe/PlatformForms.vfr | 67 ++
> > .../Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h | 50 ++
> > .../SimicsOpenBoardPkg/PlatformPei/Platform.h | 93 +++
> > .../SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf | 109 +++
> > .../SiliconPolicyInitLib/SiliconPolicyInitLib.inf | 38 +
> > .../SiliconPolicyUpdateLib.inf | 35 +
> > .../SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec | 168 ++++
> > .../SmbiosPlatformDxe/SmbiosPlatformDxe.h | 38 +
> > .../SmbiosPlatformDxe/SmbiosPlatformDxe.inf | 51 ++
> > 46 files changed, 8531 insertions(+)
> > 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/SerializeVariablesLib/SerializeVaria
> > blesLib.c
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
> > create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
> > create mode 100644 Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconP
> > olicyInitLib.c
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Silic
> > onPolicyUpdateLib.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/SimicsX58PlatformConfig.h
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateMap
> > .h
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> > 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/LoadLinuxLib.inf
> > 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/SerializeVariablesLib/SerializeVaria
> > blesLib.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVaria
> > blesLib.inf
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
> > create mode 100644
> Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/SiliconP
> > olicyInitLib.inf
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Silic
> > onPolicyUpdateLib.inf
> > create mode 100644
> > Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.h
> > create mode 100644
> >
> Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.i
> > nf
> >
> > diff --git a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> > b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> > new file mode 100644
> > index 0000000000..43a2dee9f6
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Linux.c
> > @@ -0,0 +1,662 @@
> > +/** @file
> > + Copyright (c) 2011 - 2014 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..624fbc37cb
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LinuxGdt.c
> > @@ -0,0 +1,175 @@
> > +/** @file
> > + Initialize GDT for Linux.
> > +
> > + Copyright (c) 2006 - 2012 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..6ba8784cf3
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/Library/NvVarsFileLib/FsAccess.c
> > @@ -0,0 +1,507 @@
> > +/** @file
> > + File System Access for NvVarsFileLib
> > +
> > + Copyright (c) 2004 - 2014 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..f60fbc6112
> > --- /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) 2009 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/SerializeVariablesLib/SerializeVa
> > riablesLib.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> > riablesLib.c
> > new file mode 100644
> > index 0000000000..c32a978550
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> > riablesLib.c
> > @@ -0,0 +1,869 @@
> > +/** @file
> > + Serialize Variables Library implementation
> > +
> > + Copyright (c) 2004 - 2011 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/PlatformDxe/Platform.c
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
> > new file mode 100644
> > index 0000000000..7bede1496d
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.c
> > @@ -0,0 +1,865 @@
> > +/** @file
> > + This driver effectuates OVMF's 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/SimicsX58PlatformConfig.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 PlatformDxeStrings[];
> > +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,
> > &gSimicsX58PlatformConfigGuid,
> > + 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
> > + PlatformDxeStrings, // 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/PlatformDxe/PlatformConfig.c
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
> > new file mode 100644
> > index 0000000000..b3b2b34064
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.c
> > @@ -0,0 +1,123 @@
> > +/** @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
> > +**/
> > +
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/UefiLib.h>
> > +#include <Library/UefiRuntimeServicesTableLib.h>
> > +#include <Guid/SimicsX58PlatformConfig.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,
> &gSimicsX58PlatformConfigGuid,
> > + 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, &gSimicsX58PlatformConfigGuid,
> > &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/PlatformPei/Cmos.c
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
> > new file mode 100644
> > index 0000000000..fa2c22116c
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.c
> > @@ -0,0 +1,57 @@
> > +/** @file
> > + PC/AT CMOS access routines
> > +
> > + Copyright (c) 2006 - 2009 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/PlatformPei/FeatureControl.c
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/FeatureControl.c
> > new file mode 100644
> > index 0000000000..692405e417
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/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/PlatformPei/Fv.c
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
> > new file mode 100644
> > index 0000000000..818d135c95
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Fv.c
> > @@ -0,0 +1,100 @@
> > +/** @file
> > + Build FV related hobs for platform.
> > +
> > + Copyright (c) 2006 - 2013 Intel Corporation. All rights reserved. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#include "PiPei.h"
> > +#include "Platform.h"
> > +#include <Library/DebugLib.h>
> > +#include <Library/HobLib.h>
> > +#include <Library/PeiServicesLib.h>
> > +#include <Library/PcdLib.h>
> > +
> > +
> > +/**
> > + 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/PlatformPei/MemDetect.c
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
> > new file mode 100644
> > index 0000000000..4c527baef2
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/MemDetect.c
> > @@ -0,0 +1,568 @@
> > +/** @file
> > + Memory Detection for Virtual Machines.
> > +
> > + Copyright (c) 2006 - 2016 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/PlatformPei/Platform.c
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
> > new file mode 100644
> > index 0000000000..e64bdc7c56
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.c
> > @@ -0,0 +1,631 @@
> > +/** @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 ();
> > + }
> > + PeiFvInitialization ();
> > + MemMapInitialization ();
> > + }
> > +
> > + MiscInitialization ();
> > + InstallFeatureControlCallback ();
> > +
> > + return EFI_SUCCESS;
> > +}
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> > PolicyInitLib.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> > PolicyInitLib.c
> > new file mode 100644
> > index 0000000000..01a9ed40d5
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> > PolicyInitLib.c
> > @@ -0,0 +1,108 @@
> > +/** @file
> > + Copyright (c) 2018 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/Sil
> > iconPolicyUpdateLib.c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> > iconPolicyUpdateLib.c
> > new file mode 100644
> > index 0000000000..6d9da67975
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> > iconPolicyUpdateLib.c
> > @@ -0,0 +1,70 @@
> > +/** @file
> > + Copyright (c) 2018 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/SmbiosPlatformDxe/SmbiosPlatformDxe
> > .c
> >
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> > .c
> > new file mode 100644
> > index 0000000000..82a2d60959
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> > .c
> > @@ -0,0 +1,148 @@
> > +/** @file
> > + This driver installs SMBIOS information for OVMF
> > +
> > + 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 OVMF
> > +
> > + @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..839626eb86
> > --- /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 - 2018 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..76a8fbc081
> > --- /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) 2008 Intel Corporation. All rights reserved. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +DefinitionBlock ("Dsdt.aml", "DSDT", 1, "INTEL ", "OVMF ", 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..6395ec11e2
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/AcpiTables/Platform.h
> > @@ -0,0 +1,75 @@
> > +/** @file
> > + Platform specific defines for constructing ACPI tables
> > +
> > + Copyright (c) 2013 - 2008 Intel Corporation. All rights reserved. <BR>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#ifndef _Platform_h_INCLUDED_
> > +#define _Platform_h_INCLUDED_
> > +
> > +#include <PiDxe.h>
> > +#include <IndustryStandard/Acpi.h>
> > +
> > +//
> > +// ACPI table information used to initialize tables.
> > +//
> > +#define EFI_ACPI_OEM_ID 'O','V','M','F',' ',' ' // OEMID 6 bytes long
> > +#define EFI_ACPI_OEM_TABLE_ID
> > SIGNATURE_64('O','V','M','F','E','D','K','2') // OEM table id 8 bytes long
> > +#define EFI_ACPI_OEM_REVISION 0x02000820
> > +#define EFI_ACPI_CREATOR_ID SIGNATURE_32('O','V','M','F')
> > +#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/SimicsX58PlatformConfig.
> > h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.
> > h
> > new file mode 100644
> > index 0000000000..f65f61d74d
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Guid/SimicsX58PlatformConfig.
> > h
> > @@ -0,0 +1,17 @@
> > +/** @file
> > + GUID for UEFI variables that are specific to OVMF configuration.
> > +
> > + Copyright (C) 2014, Red Hat, Inc.
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#ifndef __SIMICSX58_PLATFORM_CONFIG_H__
> > +#define __SIMICSX58_PLATFORM_CONFIG_H__
> > +
> > +#define SIMICSX58_PLATFORM_CONFIG_GUID \
> > +{0xeed35f57, 0x4ff2, 0x4244, {0xb8, 0x3a, 0xea, 0x71, 0x5f, 0xd3, 0x59,
> > 0xa5}}
> > +
> > +extern EFI_GUID gSimicsX58PlatformConfigGuid;
> > +
> > +#endif
> > diff --git
> > a/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> > b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> > new file mode 100644
> > index 0000000000..36c08176d1
> > --- /dev/null
> > +++
> > b/Platform/Intel/SimicsOpenBoardPkg/Include/IndustryStandard/X58Ich10.h
> > @@ -0,0 +1,106 @@
> > +/** @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>
> > +
> > +//
> > +// 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/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> > b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> > new file mode 100644
> > index 0000000000..12aeb1227c
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaAcpi.h
> > @@ -0,0 +1,298 @@
> > +/** @file
> > + EFI ISA ACPI Protocol is used to enumerate and manage all the ISA
> controllers
> > on
> > + the platform's ISA Bus.
> > +
> > +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef __ISA_ACPI_H_
> > +#define __ISA_ACPI_H_
> > +
> > +///
> > +/// Global ID for the EFI ISA ACPI Protocol.
> > +///
> > +#define EFI_ISA_ACPI_PROTOCOL_GUID \
> > + { \
> > + 0x64a892dc, 0x5561, 0x4536, { 0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33,
> > 0x55 } \
> > + }
> > +
> > +///
> > +/// Forward declaration fo the EFI ISA ACPI Protocol
> > +///
> > +typedef struct _EFI_ISA_ACPI_PROTOCOL EFI_ISA_ACPI_PROTOCOL;
> > +
> > +///
> > +/// ISA ACPI Protocol interrupt resource attributes.
> > +///
> > +#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_EDGE_SENSITIVE 0x01 ///<
> > Edge triggered interrupt on a rising edge.
> > +#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_EDGE_SENSITIVE 0x02 ///<
> > Edge triggered interrupt on a falling edge.
> > +#define EFI_ISA_ACPI_IRQ_TYPE_HIGH_TRUE_LEVEL_SENSITIVE 0x04 ///<
> > Level sensitive interrupt active high.
> > +#define EFI_ISA_ACPI_IRQ_TYPE_LOW_TRUE_LEVEL_SENSITIVE 0x08 ///<
> > Level sensitive interrupt active low.
> > +
> > +///
> > +/// ISA ACPI Protocol DMA resource attributes.
> > +///
> > +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_MASK 0x03 ///< Bit
> mask
> > of supported DMA speed attributes.
> > +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_COMPATIBILITY 0x00 ///<
> ISA
> > controller supports compatibility mode DMA transfers.
> > +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_A 0x01 ///< ISA
> > controller supports type A DMA transfers.
> > +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_B 0x02 ///< ISA
> > controller supports type B DMA transfers.
> > +#define EFI_ISA_ACPI_DMA_SPEED_TYPE_F 0x03 ///< ISA
> > controller supports type F DMA transfers.
> > +#define EFI_ISA_ACPI_DMA_COUNT_BY_BYTE 0x04 ///< ISA
> > controller increments DMA address by bytes (8-bit).
> > +#define EFI_ISA_ACPI_DMA_COUNT_BY_WORD 0x08 ///< ISA
> > controller increments DMA address by words (16-bit).
> > +#define EFI_ISA_ACPI_DMA_BUS_MASTER 0x10 ///< ISA
> > controller is a DMA bus master.
> > +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT 0x20 ///< ISA
> > controller only supports 8-bit DMA transfers.
> > +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_8_BIT_AND_16_BIT 0x40
> > ///< ISA controller both 8-bit and 16-bit DMA transfers.
> > +#define EFI_ISA_ACPI_DMA_TRANSFER_TYPE_16_BIT 0x80 ///< ISA
> > controller only supports 16-bit DMA transfers.
> > +
> > +///
> > +/// ISA ACPI Protocol MMIO resource attributes
> > +///
> > +#define EFI_ISA_ACPI_MEMORY_WIDTH_MASK 0x03 ///< Bit
> mask
> > of supported ISA memory width attributes.
> > +#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT 0x00 ///< ISA
> > MMIO region only supports 8-bit access.
> > +#define EFI_ISA_ACPI_MEMORY_WIDTH_16_BIT 0x01 ///< ISA
> > MMIO region only supports 16-bit access.
> > +#define EFI_ISA_ACPI_MEMORY_WIDTH_8_BIT_AND_16_BIT 0x02 ///<
> > ISA MMIO region supports both 8-bit and 16-bit access.
> > +#define EFI_ISA_ACPI_MEMORY_WRITEABLE 0x04 ///< ISA
> MMIO
> > region supports write transactions.
> > +#define EFI_ISA_ACPI_MEMORY_CACHEABLE 0x08 ///< ISA
> MMIO
> > region supports being cached.
> > +#define EFI_ISA_ACPI_MEMORY_SHADOWABLE 0x10 ///< ISA
> > MMIO region may be shadowed.
> > +#define EFI_ISA_ACPI_MEMORY_EXPANSION_ROM 0x20 ///< ISA
> > MMIO region is an expansion ROM.
> > +
> > +///
> > +/// ISA ACPI Protocol I/O resource attributes
> > +///
> > +#define EFI_ISA_ACPI_IO_DECODE_10_BITS 0x01 ///< ISA
> > controllers uses a 10-bit address decoder for I/O cycles.
> > +#define EFI_ISA_ACPI_IO_DECODE_16_BITS 0x02 ///< ISA
> > controllers uses a 16-bit address decoder for I/O cycles.
> > +
> > +///
> > +/// EFI ISA ACPI resource type
> > +///
> > +typedef enum {
> > + EfiIsaAcpiResourceEndOfList, ///< Marks the end if a resource list.
> > + EfiIsaAcpiResourceIo, ///< ISA I/O port resource range.
> > + EfiIsaAcpiResourceMemory, ///< ISA MMIO resource range.
> > + EfiIsaAcpiResourceDma, ///< ISA DMA resource.
> > + EfiIsaAcpiResourceInterrupt ///< ISA interrupt resource.
> > +} EFI_ISA_ACPI_RESOURCE_TYPE;
> > +
> > +///
> > +/// EFI ISA ACPI generic resource structure
> > +///
> > +typedef struct {
> > + EFI_ISA_ACPI_RESOURCE_TYPE Type; ///< The type of resource (I/O,
> > MMIO, DMA, Interrupt).
> > + UINT32 Attribute; ///< Bit mask of attributes associated with
> this
> > resource. See EFI_ISA_ACPI_xxx macros for valid combinations.
> > + UINT32 StartRange; ///< The start of the resource range.
> > + UINT32 EndRange; ///< The end of the resource range.
> > +} EFI_ISA_ACPI_RESOURCE;
> > +
> > +///
> > +/// EFI ISA ACPI resource device identifier
> > +///
> > +typedef struct {
> > + UINT32 HID; ///< The ACPI Hardware Identifier value associated with an
> ISA
> > controller. Matchs ACPI DSDT contents.
> > + UINT32 UID; ///< The ACPI Unique Identifier value associated with an ISA
> > controller. Matches ACPI DSDT contents.
> > +} EFI_ISA_ACPI_DEVICE_ID;
> > +
> > +///
> > +/// EFI ISA ACPI resource list
> > +///
> > +typedef struct {
> > + EFI_ISA_ACPI_DEVICE_ID Device; ///< The ACPI HID/UID associated
> with
> > an ISA controller.
> > + EFI_ISA_ACPI_RESOURCE *ResourceItem; ///< A pointer to the list of
> > resources associated with an ISA controller.
> > +} EFI_ISA_ACPI_RESOURCE_LIST;
> > +
> > +/**
> > + Enumerates the ISA controllers on an ISA bus.
> > +
> > + This service allows all the ISA controllers on an ISA bus to be enumerated. If
> > + Device is a pointer to a NULL value, then the first ISA controller on the ISA
> > + bus is returned in Device and EFI_SUCCESS is returned. If Device is a pointer
> > + to a value that was returned on a prior call to DeviceEnumerate(), then the
> > next
> > + ISA controller on the ISA bus is returned in Device and EFI_SUCCESS is
> > returned.
> > + If Device is a pointer to the last ISA controller on the ISA bus, then
> > + EFI_NOT_FOUND is returned.
> > +
> > + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> > + @param[out] Device The pointer to an ISA controller named by ACPI
> > HID/UID.
> > +
> > + @retval EFI_SUCCESS The next ISA controller on the ISA bus was returned.
> > + @retval EFI_NOT_FOUND No device found.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_ACPI_DEVICE_ENUMERATE)(
> > + IN EFI_ISA_ACPI_PROTOCOL *This,
> > + OUT EFI_ISA_ACPI_DEVICE_ID **Device
> > + );
> > +
> > +/**
> > + Sets the power state of an ISA controller.
> > +
> > + This services sets the power state of the ISA controller specified by Device to
> > + the power state specified by OnOff. TRUE denotes on, FALSE denotes off.
> > + If the power state is sucessfully set on the ISA Controller, then
> > + EFI_SUCCESS is returned.
> > +
> > + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> > + @param[in] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> > + @param[in] OnOff TRUE denotes on, FALSE denotes off.
> > +
> > + @retval EFI_SUCCESS Successfully set the power state of the ISA
> controller.
> > + @retval Other The ISA controller could not be placed in the requested
> > power state.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_ACPI_SET_DEVICE_POWER)(
> > + IN EFI_ISA_ACPI_PROTOCOL *This,
> > + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> > + IN BOOLEAN OnOff
> > + );
> > +
> > +/**
> > + Retrieves the current set of resources associated with an ISA controller.
> > +
> > + Retrieves the set of I/O, MMIO, DMA, and interrupt resources currently
> > + assigned to the ISA controller specified by Device. These resources
> > + are returned in ResourceList.
> > +
> > + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL
> instance.
> > + @param[in] Device The pointer to an ISA controller named by ACPI
> > HID/UID.
> > + @param[out] ResourceList The pointer to the current resource list for
> Device.
> > +
> > + @retval EFI_SUCCESS Successfully retrieved the current resource list.
> > + @retval EFI_NOT_FOUND The resource list could not be retrieved.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_ACPI_GET_CUR_RESOURCE)(
> > + IN EFI_ISA_ACPI_PROTOCOL *This,
> > + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> > + OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
> > + );
> > +
> > +/**
> > + Retrieves the set of possible resources that may be assigned to an ISA
> > controller
> > + with SetResource().
> > +
> > + Retrieves the possible sets of I/O, MMIO, DMA, and interrupt resources for
> > the
> > + ISA controller specified by Device. The sets are returned in ResourceList.
> > +
> > + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL
> instance.
> > + @param[in] Device The pointer to an ISA controller named by ACPI
> > HID/UID.
> > + @param[out] ResourceList The pointer to the returned list of resource lists.
> > +
> > + @retval EFI_UNSUPPORTED This service is not supported.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_ACPI_GET_POS_RESOURCE)(
> > + IN EFI_ISA_ACPI_PROTOCOL *This,
> > + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> > + OUT EFI_ISA_ACPI_RESOURCE_LIST **ResourceList
> > + );
> > +
> > +/**
> > + Assigns resources to an ISA controller.
> > +
> > + Assigns the I/O, MMIO, DMA, and interrupt resources specified by
> > ResourceList
> > + to the ISA controller specified by Device. ResourceList must match a
> resource
> > list returned by GetPosResource() for the same ISA controller.
> > +
> > + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL
> instance.
> > + @param[in] Device The pointer to an ISA controller named by ACPI
> > HID/UID.
> > + @param[in] ResourceList The pointer to a resources list that must be one
> of
> > the
> > + resource lists returned by GetPosResource() for the
> > + ISA controller specified by Device.
> > +
> > + @retval EFI_SUCCESS Successfully set resources on the ISA controller.
> > + @retval Other The resources could not be set for the ISA controller.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_ACPI_SET_RESOURCE)(
> > + IN EFI_ISA_ACPI_PROTOCOL *This,
> > + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> > + IN EFI_ISA_ACPI_RESOURCE_LIST *ResourceList
> > + );
> > +
> > +/**
> > + Enables or disables an ISA controller.
> > +
> > + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> > + @param[in] Device The pointer to the ISA controller to enable/disable.
> > + @param[in] Enable TRUE to enable the ISA controller. FALSE to disable the
> > + ISA controller.
> > +
> > + @retval EFI_SUCCESS Successfully enabled/disabled the ISA controller.
> > + @retval Other The ISA controller could not be placed in the requested
> > state.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_ACPI_ENABLE_DEVICE)(
> > + IN EFI_ISA_ACPI_PROTOCOL *This,
> > + IN EFI_ISA_ACPI_DEVICE_ID *Device,
> > + IN BOOLEAN Enable
> > + );
> > +
> > +/**
> > + Initializes an ISA controller, so that it can be used. This service must be
> called
> > + before SetResource(), EnableDevice(), or SetPower() will behave as
> expected.
> > +
> > + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> > + @param[in] Device The pointer to an ISA controller named by ACPI
> HID/UID.
> > +
> > + @retval EFI_SUCCESS Successfully initialized an ISA controller.
> > + @retval Other The ISA controller could not be initialized.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_ACPI_INIT_DEVICE)(
> > + IN EFI_ISA_ACPI_PROTOCOL *This,
> > + IN EFI_ISA_ACPI_DEVICE_ID *Device
> > + );
> > +
> > +/**
> > + Initializes all the HW states required for the ISA controllers on the ISA bus
> > + to be enumerated and managed by the rest of the services in this prorotol.
> > + This service must be called before any of the other services in this
> > + protocol will function as expected.
> > +
> > + @param[in] This The pointer to the EFI_ISA_ACPI_PROTOCOL instance.
> > +
> > + @retval EFI_SUCCESS Successfully initialized all required hardware states.
> > + @retval Other The ISA interface could not be initialized.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_ACPI_INTERFACE_INIT)(
> > + IN EFI_ISA_ACPI_PROTOCOL *This
> > + );
> > +
> > +///
> > +/// The EFI_ISA_ACPI_PROTOCOL provides the services to enumerate and
> > manage
> > +/// ISA controllers on an ISA bus. These services include the ability to
> initialize,
> > +/// enable, disable, and manage the power state of ISA controllers. It also
> > +/// includes services to query current resources, query possible resources,
> > +/// and assign resources to an ISA controller.
> > +///
> > +struct _EFI_ISA_ACPI_PROTOCOL {
> > + EFI_ISA_ACPI_DEVICE_ENUMERATE DeviceEnumerate;
> > + EFI_ISA_ACPI_SET_DEVICE_POWER SetPower;
> > + EFI_ISA_ACPI_GET_CUR_RESOURCE GetCurResource;
> > + EFI_ISA_ACPI_GET_POS_RESOURCE GetPosResource;
> > + EFI_ISA_ACPI_SET_RESOURCE SetResource;
> > + EFI_ISA_ACPI_ENABLE_DEVICE EnableDevice;
> > + EFI_ISA_ACPI_INIT_DEVICE InitDevice;
> > + EFI_ISA_ACPI_INTERFACE_INIT InterfaceInit;
> > +};
> > +
> > +extern EFI_GUID gEfiIsaAcpiProtocolGuid;
> > +
> > +#endif
> > diff --git a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> > b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> > new file mode 100644
> > index 0000000000..30000305fb
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/IsaIo.h
> > @@ -0,0 +1,356 @@
> > +/** @file
> > + ISA I/O Protocol is used by ISA device drivers to perform I/O, MMIO and
> DMA
> > + operations on the ISA controllers they manage.
> > +
> > +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef _EFI_ISA_IO_H_
> > +#define _EFI_ISA_IO_H_
> > +
> > +#include <Protocol/IsaAcpi.h>
> > +
> > +///
> > +/// Global ID for the EFI_ISA_IO_PROTOCOL
> > +///
> > +#define EFI_ISA_IO_PROTOCOL_GUID \
> > + { \
> > + 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1,
> > 0x4d } \
> > + }
> > +
> > +///
> > +/// Forward declaration for the EFI_ISA_IO_PROTOCOL.
> > +///
> > +typedef struct _EFI_ISA_IO_PROTOCOL EFI_ISA_IO_PROTOCOL;
> > +
> > +///
> > +/// Width of EFI_ISA_IO_PROTOCOL I/O Port and MMIO operations.
> > +///
> > +typedef enum {
> > + EfiIsaIoWidthUint8 = 0, ///< 8-bit operation.
> > + EfiIsaIoWidthUint16, ///< 16-bit operation.
> > + EfiIsaIoWidthUint32, ///< 32-bit operation
> > + EfiIsaIoWidthReserved,
> > + EfiIsaIoWidthFifoUint8, ///< 8-bit FIFO operation.
> > + EfiIsaIoWidthFifoUint16, ///< 16-bit FIFO operation.
> > + EfiIsaIoWidthFifoUint32, ///< 32-bit FIFO operation.
> > + EfiIsaIoWidthFifoReserved,
> > + EfiIsaIoWidthFillUint8, ///< 8-bit Fill operation.
> > + EfiIsaIoWidthFillUint16, ///< 16-bit Fill operation.
> > + EfiIsaIoWidthFillUint32, ///< 32-bit Fill operation.
> > + EfiIsaIoWidthFillReserved,
> > + EfiIsaIoWidthMaximum
> > +} EFI_ISA_IO_PROTOCOL_WIDTH;
> > +
> > +///
> > +/// Attributes for the EFI_ISA_IO_PROTOCOL common DMA buffer
> allocations.
> > +///
> > +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x080 ///<
> > Map a memory range so write are combined.
> > +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_CACHED 0x800 ///< Map a
> > memory range so all read and write accesses are cached.
> > +#define EFI_ISA_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000 ///<
> Disable
> > a memory range.
> > +
> > +///
> > +/// Channel attribute for EFI_ISA_IO_PROTOCOL slave DMA requests
> > +///
> > +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_COMPATIBLE 0x001
> > ///< Set the speed of the DMA transfer in compatible mode.
> > +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_A 0x002 ///<
> Not
> > supported.
> > +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_B 0x004 ///<
> Not
> > supported.
> > +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SPEED_C 0x008 ///<
> Not
> > supported.
> > +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_8 0x010 ///<
> > Request 8-bit DMA transfers. Only available on channels 0..3.
> > +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_WIDTH_16 0x020 ///<
> > Request 16-bit DMA transfers. Only available on channels 4..7.
> > +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_SINGLE_MODE 0x040
> ///<
> > Request a single DMA transfer.
> > +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_DEMAND_MODE 0x080
> > ///< Request multiple DMA transfers until TC (Terminal Count) or EOP (End of
> > Process).
> > +#define EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_AUTO_INITIALIZE 0x100
> ///<
> > Automatically reload base and count at the end of the DMA transfer.
> > +
> > +///
> > +/// The DMA opreration type for EFI_ISA_IO_PROTOCOL DMA requests.
> > +///
> > +typedef enum {
> > + ///
> > + /// A read operation from system memory by a bus master.
> > + ///
> > + EfiIsaIoOperationBusMasterRead,
> > + ///
> > + /// A write operation to system memory by a bus master.
> > + ///
> > + EfiIsaIoOperationBusMasterWrite,
> > + ///
> > + /// Provides both read and write access to system memory by both the
> > processor
> > + /// and a bus master. The buffer is coherent from both the processor's and
> > the
> > + /// bus master's point of view.
> > + ///
> > + EfiIsaIoOperationBusMasterCommonBuffer,
> > + ///
> > + /// A read operation from system memory by a slave device.
> > + ///
> > + EfiIsaIoOperationSlaveRead,
> > + ///
> > + /// A write operation to system memory by a slave master.
> > + ///
> > + EfiIsaIoOperationSlaveWrite,
> > + EfiIsaIoOperationMaximum
> > +} EFI_ISA_IO_PROTOCOL_OPERATION;
> > +
> > +/**
> > + Performs ISA I/O and MMIO Read/Write Cycles
> > +
> > + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> > + @param[in] Width Specifies the width of the I/O or MMIO operation.
> > + @param[in] Offset The offset into the ISA I/O or MMIO space to start
> the
> > + operation.
> > + @param[in] Count The number of I/O or MMIO operations to perform.
> > + @param[in, out] Buffer For read operations, the destination buffer to
> store
> > + the results. For write operations, the source buffer to
> > + write data from.
> > +
> > + @retval EFI_SUCCESS The data was successfully read from or written
> to
> > the device.
> > + @retval EFI_UNSUPPORTED The Offset is not valid for this device.
> > + @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
> > + @retval EFI_OUT_OF_RESOURCES The request could not be completed
> due
> > to a lack of resources.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_IO_PROTOCOL_IO_MEM)(
> > + IN EFI_ISA_IO_PROTOCOL *This,
> > + IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
> > + IN UINT32 Offset,
> > + IN UINTN Count,
> > + IN OUT VOID *Buffer
> > + );
> > +
> > +///
> > +/// Structure of functions for accessing ISA I/O and MMIO space.
> > +///
> > +typedef struct {
> > + ///
> > + /// Read from ISA I/O or MMIO space.
> > + ///
> > + EFI_ISA_IO_PROTOCOL_IO_MEM Read;
> > + ///
> > + /// Write to ISA I/O or MMIO space.
> > + ///
> > + EFI_ISA_IO_PROTOCOL_IO_MEM Write;
> > +} EFI_ISA_IO_PROTOCOL_ACCESS;
> > +
> > +/**
> > + Copies data from one region of ISA MMIO space to another region of ISA
> > + MMIO space.
> > +
> > + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> > + @param[in] Width Specifies the width of the MMIO copy operation.
> > + @param[in] DestOffset The offset of the destination in ISA MMIO space.
> > + @param[in] SrcOffset The offset of the source in ISA MMIO space.
> > + @param[in] Count The number tranfers to perform for this copy
> > operation.
> > +
> > + @retval EFI_SUCCESS The data was copied sucessfully.
> > + @retval EFI_UNSUPPORTED The DestOffset or SrcOffset is not valid for
> > this device.
> > + @retval EFI_INVALID_PARAMETER Width or Count, or both, were invalid.
> > + @retval EFI_OUT_OF_RESOURCES The request could not be completed
> due
> > to a lack of resources.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_IO_PROTOCOL_COPY_MEM)(
> > + IN EFI_ISA_IO_PROTOCOL *This,
> > + IN EFI_ISA_IO_PROTOCOL_WIDTH Width,
> > + IN UINT32 DestOffset,
> > + IN UINT32 SrcOffset,
> > + IN UINTN Count
> > + );
> > +
> > +/**
> > + Maps a memory region for DMA.
> > +
> > + This function returns the device-specific addresses required to access system
> > memory.
> > + This function is used to map system memory for ISA DMA operations. All
> ISA
> > DMA
> > + operations must be performed through their mapped addresses, and such
> > mappings must
> > + be freed with EFI_ISA_IO_PROTOCOL.Unmap() after the DMA operation is
> > completed.
> > +
> > + If the DMA operation is a single read or write data transfer through an ISA
> bus
> > + master, then EfiIsaIoOperationBusMasterRead or
> > EfiIsaIoOperationBusMasterWrite
> > + is used and the range is unmapped to complete the operation. If the DMA
> > operation
> > + is a single read or write data transfer through an ISA slave controller, then
> > + EfiIsaIoOperationSlaveRead or EfiIsaIoOperationSlaveWrite is used and the
> > range
> > + is unmapped to complete the operation.
> > +
> > + If performing a DMA read operation, all the data must be present in system
> > memory before the Map() is performed. Similarly,
> > + if performing a DMA write operation, the data must not be accessed in
> system
> > + memory until EFI_ISA_IO_PROTOCOL.Unmap() is performed. Bus master
> > operations that
> > + require both read and write access or require multiple host device
> > interactions
> > + within the same mapped region must use
> > EfiIsaIoOperationBusMasterCommonBuffer.
> > + However, only memory allocated via the
> > EFI_ISA_IO_PROTOCOL.AllocateBuffer() interface
> > + is guaranteed to be able to be mapped for this operation type. In all
> mapping
> > + requests the NumberOfBytes returned may be less than originally
> requested.
> > It is
> > + the caller's responsibility to make additional requests to complete the entire
> > + transfer.
> > +
> > + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL
> instance.
> > + @param[in] Operation Indicates the type of DMA (slave or bus
> > master),
> > + and if the DMA operation is going to read or
> > + write to system memory.
> > + @param[in] ChannelNumber The slave channel number to use for this
> > DMA
> > + operation. If Operation and ChannelAttributes
> > + shows that this device performs bus mastering
> > + DMA, then this field is ignored. The legal
> > + range for this field is 0..7.
> > + @param[in] ChannelAttributes A bitmask of the attributes used to
> > configure
> > + the slave DMA channel for this DMA operation.
> > + See EFI_ISA_IO_SLAVE_DMA_ATTRIBUTE_* for the
> > + legal bit combinations.
> > + @param[in] HostAddress The system memory address to map to the
> > device.
> > + @param[in, out] NumberOfBytes On input the number of bytes to map.
> > On
> > + output the number of bytes that were mapped.
> > + @param[out] DeviceAddress The resulting map address for the bus
> > master
> > + device to use to access the hosts HostAddress.
> > + @param[out] Mapping A returned value that must be passed to
> into
> > + EFI_ISA_IO_PROTOCOL.Unmap() to free all the the
> > + resources associated with this map request.
> > +
> > + @retval EFI_SUCCESS The range was mapped for the returned
> > NumberOfBytes.
> > + @retval EFI_INVALID_PARAMETER The Operation is undefined.
> > + @retval EFI_INVALID_PARAMETER The HostAddress is undefined.
> > + @retval EFI_UNSUPPORTED The HostAddress can not be mapped as a
> > common buffer.
> > + @retval EFI_DEVICE_ERROR The system hardware could not map the
> > requested address.
> > + @retval EFI_OUT_OF_RESOURCES The memory pages could not be
> > allocated.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_IO_PROTOCOL_MAP)(
> > + IN EFI_ISA_IO_PROTOCOL *This,
> > + IN EFI_ISA_IO_PROTOCOL_OPERATION Operation,
> > + IN UINT8 ChannelNumber OPTIONAL,
> > + IN UINT32 ChannelAttributes,
> > + IN VOID *HostAddress,
> > + IN OUT UINTN *NumberOfBytes,
> > + OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
> > + OUT VOID **Mapping
> > + );
> > +
> > +/**
> > + Unmaps a memory region that was previously mapped with
> > EFI_ISA_IO_PROTOCOL.Map().
> > +
> > + The EFI_ISA_IO_PROTOCOL.Map() operation is completed and any
> > corresponding
> > + resources are released. If the operation was EfiIsaIoOperationSlaveWrite
> > + or EfiIsaIoOperationBusMasterWrite, the data is committed to system
> > memory.
> > + Any resources used for the mapping are freed.
> > +
> > + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> > + @param[in] Mapping The mapping value returned from
> > EFI_ISA_IO_PROTOCOL.Map().
> > +
> > + @retval EFI_SUCCESS The memory region was unmapped.
> > + @retval EFI_DEVICE_ERROR The data was not committed to the target
> > system memory.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_IO_PROTOCOL_UNMAP)(
> > + IN EFI_ISA_IO_PROTOCOL *This,
> > + IN VOID *Mapping
> > + );
> > +
> > +/**
> > + Allocates pages that are suitable for an
> > EfiIsaIoOperationBusMasterCommonBuffer
> > + mapping.
> > +
> > + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> > + @param[in] Type The type allocation to perform.
> > + @param[in] MemoryType The type of memory to allocate.
> > + @param[in] Pages The number of pages to allocate.
> > + @param[out] HostAddress A pointer to store the base address of the
> > allocated range.
> > + @param[in] Attributes The requested bit mask of attributes for the
> > allocated range.
> > +
> > + @retval EFI_SUCCESS The requested memory pages were allocated.
> > + @retval EFI_INVALID_PARAMETER Type is invalid.
> > + @retval EFI_INVALID_PARAMETER MemoryType is invalid.
> > + @retval EFI_INVALID_PARAMETER HostAddress is NULL.
> > + @retval EFI_UNSUPPORTED Attributes is unsupported.
> > + @retval EFI_UNSUPPORTED The memory range specified by
> > HostAddress, Pages,
> > + and Type is not available for common buffer use.
> > + @retval EFI_OUT_OF_RESOURCES The memory pages could not be
> > allocated.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER)(
> > + IN EFI_ISA_IO_PROTOCOL *This,
> > + IN EFI_ALLOCATE_TYPE Type,
> > + IN EFI_MEMORY_TYPE MemoryType,
> > + IN UINTN Pages,
> > + OUT VOID **HostAddress,
> > + IN UINT64 Attributes
> > + );
> > +
> > +/**
> > + Frees a common buffer that was allocated with
> > EFI_ISA_IO_PROTOCOL.AllocateBuffer().
> > +
> > + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> > + @param[in] Pages The number of pages to free from the previously
> > allocated common buffer.
> > + @param[in] HostAddress The base address of the previously allocated
> > common buffer.
> > +
> > +
> > + @retval EFI_SUCCESS The requested memory pages were freed.
> > + @retval EFI_INVALID_PARAMETER The memory was not allocated with
> > EFI_ISA_IO.AllocateBufer().
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_IO_PROTOCOL_FREE_BUFFER)(
> > + IN EFI_ISA_IO_PROTOCOL *This,
> > + IN UINTN Pages,
> > + IN VOID *HostAddress
> > + );
> > +
> > +/**
> > + Flushes a DMA buffer, which forces all DMA posted write transactions to
> > complete.
> > +
> > + @param[in] This A pointer to the EFI_ISA_IO_PROTOCOL instance.
> > +
> > + @retval EFI_SUCCESS The DMA buffers were flushed.
> > + @retval EFI_DEVICE_ERROR The buffers were not flushed due to a
> > hardware error.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_ISA_IO_PROTOCOL_FLUSH)(
> > + IN EFI_ISA_IO_PROTOCOL *This
> > + );
> > +
> > +///
> > +/// The EFI_ISA_IO_PROTOCOL provides the basic Memory, I/O, and DMA
> > interfaces
> > +/// used to abstract accesses to ISA controllers. There is one
> > EFI_ISA_IO_PROTOCOL
> > +/// instance for each ISA controller on a ISA bus. A device driver that wishes
> > +/// to manage an ISA controller in a system will have to retrieve the
> > +/// ISA_PCI_IO_PROTOCOL instance associated with the ISA controller.
> > +///
> > +struct _EFI_ISA_IO_PROTOCOL {
> > + EFI_ISA_IO_PROTOCOL_ACCESS Mem;
> > + EFI_ISA_IO_PROTOCOL_ACCESS Io;
> > + EFI_ISA_IO_PROTOCOL_COPY_MEM CopyMem;
> > + EFI_ISA_IO_PROTOCOL_MAP Map;
> > + EFI_ISA_IO_PROTOCOL_UNMAP Unmap;
> > + EFI_ISA_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer;
> > + EFI_ISA_IO_PROTOCOL_FREE_BUFFER FreeBuffer;
> > + EFI_ISA_IO_PROTOCOL_FLUSH Flush;
> > + ///
> > + /// The list of I/O , MMIO, DMA, and Interrupt resources associated with the
> > + /// ISA controller abstracted by this instance of the EFI_ISA_IO_PROTOCOL.
> > + ///
> > + EFI_ISA_ACPI_RESOURCE_LIST *ResourceList;
> > + ///
> > + /// The size, in bytes, of the ROM image.
> > + ///
> > + UINT32 RomSize;
> > + ///
> > + /// A pointer to the in memory copy of the ROM image. The ISA Bus Driver is
> > responsible
> > + /// for allocating memory for the ROM image, and copying the contents of
> the
> > ROM to memory
> > + /// during ISA Bus initialization.
> > + ///
> > + VOID *RomImage;
> > +};
> > +
> > +extern EFI_GUID gEfiIsaIoProtocolGuid;
> > +
> > +#endif
> > diff --git
> a/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> > b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> > new file mode 100644
> > index 0000000000..c38f2feba7
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/Protocol/Legacy8259.h
> > @@ -0,0 +1,291 @@
> > +/** @file
> > + This protocol abstracts the 8259 interrupt controller. This includes
> > + PCI IRQ routing needed to program the PCI Interrupt Line register.
> > +
> > + Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > + @par Revision Reference:
> > + This protocol is defined in Framework for EFI Compatibility Support Module
> > spec
> > + Version 0.97.
> > +
> > +**/
> > +
> > +#ifndef _EFI_LEGACY_8259_H_
> > +#define _EFI_LEGACY_8259_H_
> > +
> > +
> > +#define EFI_LEGACY_8259_PROTOCOL_GUID \
> > + { \
> > + 0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed,
> > 0xc1 } \
> > + }
> > +
> > +typedef struct _EFI_LEGACY_8259_PROTOCOL
> > EFI_LEGACY_8259_PROTOCOL;
> > +
> > +typedef enum {
> > + Efi8259Irq0,
> > + Efi8259Irq1,
> > + Efi8259Irq2,
> > + Efi8259Irq3,
> > + Efi8259Irq4,
> > + Efi8259Irq5,
> > + Efi8259Irq6,
> > + Efi8259Irq7,
> > + Efi8259Irq8,
> > + Efi8259Irq9,
> > + Efi8259Irq10,
> > + Efi8259Irq11,
> > + Efi8259Irq12,
> > + Efi8259Irq13,
> > + Efi8259Irq14,
> > + Efi8259Irq15,
> > + Efi8259IrqMax
> > +} EFI_8259_IRQ;
> > +
> > +typedef enum {
> > + Efi8259LegacyMode,
> > + Efi8259ProtectedMode,
> > + Efi8259MaxMode
> > +} EFI_8259_MODE;
> > +
> > +/**
> > + Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
> > + the legacy mode mask and the protected mode mask. The base address for
> > the 8259
> > + is different for legacy and protected mode, so two masks are required.
> > +
> > + @param This The protocol instance pointer.
> > + @param MasterBase The base vector for the Master PIC in the 8259
> > controller.
> > + @param SlaveBase The base vector for the Slave PIC in the 8259
> > controller.
> > +
> > + @retval EFI_SUCCESS The new bases were programmed.
> > + @retval EFI_DEVICE_ERROR A device error occured programming the
> > vector bases.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_8259_SET_VECTOR_BASE)(
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN UINT8 MasterBase,
> > + IN UINT8 SlaveBase
> > + );
> > +
> > +/**
> > + Get the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
> > + the legacy mode mask and the protected mode mask. The base address for
> > the 8259
> > + is different for legacy and protected mode, so two masks are required.
> > +
> > + @param This The protocol instance pointer.
> > + @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15.
> > + @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> > + @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15.
> > + @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> > +
> > + @retval EFI_SUCCESS 8259 status returned.
> > + @retval EFI_DEVICE_ERROR Error reading 8259.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_8259_GET_MASK)(
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + OUT UINT16 *LegacyMask, OPTIONAL
> > + OUT UINT16 *LegacyEdgeLevel, OPTIONAL
> > + OUT UINT16 *ProtectedMask, OPTIONAL
> > + OUT UINT16 *ProtectedEdgeLevel OPTIONAL
> > + );
> > +
> > +/**
> > + Set the 8259 interrupt masks for Irq0 - Irq15. A different mask exists for
> > + the legacy mode mask and the protected mode mask. The base address for
> > the 8259
> > + is different for legacy and protected mode, so two masks are required.
> > + Also set the edge/level masks.
> > +
> > + @param This The protocol instance pointer.
> > + @param LegacyMask Bit 0 is Irq0 - Bit 15 is Irq15.
> > + @param LegacyEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> > + @param ProtectedMask Bit 0 is Irq0 - Bit 15 is Irq15.
> > + @param ProtectedEdgeLevel Bit 0 is Irq0 - Bit 15 is Irq15.
> > +
> > + @retval EFI_SUCCESS 8259 status returned.
> > + @retval EFI_DEVICE_ERROR Error writing 8259.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_8259_SET_MASK)(
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN UINT16 *LegacyMask, OPTIONAL
> > + IN UINT16 *LegacyEdgeLevel, OPTIONAL
> > + IN UINT16 *ProtectedMask, OPTIONAL
> > + IN UINT16 *ProtectedEdgeLevel OPTIONAL
> > + );
> > +
> > +/**
> > + Set the 8259 mode of operation. The base address for the 8259 is different
> > for
> > + legacy and protected mode. The legacy mode requires the master 8259 to
> > have a
> > + master base of 0x08 and the slave base of 0x70. The protected mode base
> > locations
> > + are not defined. Interrupts must be masked by the caller before this
> function
> > + is called. The interrupt mask from the current mode is saved. The interrupt
> > + mask for the new mode is Mask, or if Mask does not exist the previously
> saved
> > + mask is used.
> > +
> > + @param This The protocol instance pointer.
> > + @param Mode The mode of operation. i.e. the real mode or
> > protected mode.
> > + @param Mask Optional interupt mask for the new mode.
> > + @param EdgeLevel Optional trigger mask for the new mode.
> > +
> > + @retval EFI_SUCCESS 8259 programmed.
> > + @retval EFI_DEVICE_ERROR Error writing to 8259.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_8259_SET_MODE)(
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_MODE Mode,
> > + IN UINT16 *Mask, OPTIONAL
> > + IN UINT16 *EdgeLevel OPTIONAL
> > + );
> > +
> > +/**
> > + Convert from IRQ to processor interrupt vector number.
> > +
> > + @param This The protocol instance pointer.
> > + @param Irq 8259 IRQ0 - IRQ15.
> > + @param Vector The processor vector number that matches an Irq.
> > +
> > + @retval EFI_SUCCESS The Vector matching Irq is returned.
> > + @retval EFI_INVALID_PARAMETER The Irq not valid.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_8259_GET_VECTOR)(
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_IRQ Irq,
> > + OUT UINT8 *Vector
> > + );
> > +
> > +/**
> > + Enable Irq by unmasking interrupt in 8259
> > +
> > + @param This The protocol instance pointer.
> > + @param Irq 8259 IRQ0 - IRQ15.
> > + @param LevelTriggered TRUE if level triggered. FALSE if edge triggered.
> > +
> > + @retval EFI_SUCCESS The Irq was enabled on 8259.
> > + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_8259_ENABLE_IRQ)(
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_IRQ Irq,
> > + IN BOOLEAN LevelTriggered
> > + );
> > +
> > +/**
> > + Disable Irq by masking interrupt in 8259
> > +
> > + @param This The protocol instance pointer.
> > + @param Irq 8259 IRQ0 - IRQ15.
> > +
> > + @retval EFI_SUCCESS The Irq was disabled on 8259.
> > + @retval EFI_INVALID_PARAMETER The Irq is not valid.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_8259_DISABLE_IRQ)(
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_IRQ Irq
> > + );
> > +
> > +/**
> > + PciHandle represents a PCI config space of a PCI function. Vector
> > + represents Interrupt Pin (from PCI config space) and it is the data
> > + that is programmed into the Interrupt Line (from the PCI config space)
> > + register.
> > +
> > + @param This The protocol instance pointer.
> > + @param PciHandle The PCI function to return the vector for.
> > + @param Vector The vector for the function it matches.
> > +
> > + @retval EFI_SUCCESS A valid Vector was returned.
> > + @retval EFI_INVALID_PARAMETER PciHandle not valid.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_8259_GET_INTERRUPT_LINE)(
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_HANDLE PciHandle,
> > + OUT UINT8 *Vector
> > + );
> > +
> > +/**
> > + Send an EOI to 8259
> > +
> > + @param This The protocol instance pointer.
> > + @param Irq 8259 IRQ0 - IRQ15.
> > +
> > + @retval EFI_SUCCESS EOI was successfully sent to 8259.
> > + @retval EFI_INVALID_PARAMETER The Irq isnot valid.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_LEGACY_8259_END_OF_INTERRUPT)(
> > + IN EFI_LEGACY_8259_PROTOCOL *This,
> > + IN EFI_8259_IRQ Irq
> > + );
> > +
> > +/**
> > + @par Protocol Description:
> > + Abstracts the 8259 and APIC hardware control between EFI usage and
> > + Compatibility16 usage.
> > +
> > + @param SetVectorBase
> > + Sets the vector bases for master and slave PICs.
> > +
> > + @param GetMask
> > + Gets IRQ and edge/level masks for 16-bit real mode and 32-bit protected
> > mode.
> > +
> > + @param SetMask
> > + Sets the IRQ and edge\level masks for 16-bit real mode and 32-bit protected
> > mode.
> > +
> > + @param SetMode
> > + Sets PIC mode to 16-bit real mode or 32-bit protected mode.
> > +
> > + @param GetVector
> > + Gets the base vector assigned to an IRQ.
> > +
> > + @param EnableIrq
> > + Enables an IRQ.
> > +
> > + @param DisableIrq
> > + Disables an IRQ.
> > +
> > + @param GetInterruptLine
> > + Gets an IRQ that is assigned to a PCI device.
> > +
> > + @param EndOfInterrupt
> > + Issues the end of interrupt command.
> > +
> > +**/
> > +struct _EFI_LEGACY_8259_PROTOCOL {
> > + EFI_LEGACY_8259_SET_VECTOR_BASE SetVectorBase;
> > + EFI_LEGACY_8259_GET_MASK GetMask;
> > + EFI_LEGACY_8259_SET_MASK SetMask;
> > + EFI_LEGACY_8259_SET_MODE SetMode;
> > + EFI_LEGACY_8259_GET_VECTOR GetVector;
> > + EFI_LEGACY_8259_ENABLE_IRQ EnableIrq;
> > + EFI_LEGACY_8259_DISABLE_IRQ DisableIrq;
> > + EFI_LEGACY_8259_GET_INTERRUPT_LINE GetInterruptLine;
> > + EFI_LEGACY_8259_END_OF_INTERRUPT EndOfInterrupt;
> > +};
> > +
> > +extern EFI_GUID gEfiLegacy8259ProtocolGuid;
> > +
> > +#endif
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateM
> > ap.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateM
> > ap.h
> > new file mode 100644
> > index 0000000000..640ac4943d
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Include/Register/X58SmramSaveStateM
> > ap.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/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> > b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> > new file mode 100644
> > index 0000000000..c79111d811
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/Include/SimicsPlatforms.h
> > @@ -0,0 +1,54 @@
> > +/** @file
> > + OVMF Platform definitions
> > +
> > + Copyright (C) 2015, Red Hat, Inc.
> > + Copyright (c) 2014, Gabriel L. Somlo <somlo@cmu.edu>
> > +
> > + SPDX-License-Identifier: BSD-2-Clause-Patent
> > +**/
> > +
> > +#ifndef __OVMF_PLATFORMS_H__
> > +#define __OVMF_PLATFORMS_H__
> > +
> > +#include <Library/PciLib.h>
> > +#include <IndustryStandard/Pci22.h>
> > +#include <IndustryStandard/X58Ich10.h>
> > +#include <IndustryStandard/I440FxPiix4.h> // TODO: remove
> > +
> > +//
> > +// 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/LoadLinuxLib/Ia32/JumpToKern
> > el.nasm
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKern
> > el.nasm
> > new file mode 100644
> > index 0000000000..3f3cd33c8a
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/Ia32/JumpToKern
> > el.nasm
> > @@ -0,0 +1,41 @@
> > +; @file
> > +; Copyright (c) 2006 - 2013 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..c4cc4dd8e7
> > --- /dev/null
> > +++
> > b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.h
> > @@ -0,0 +1,52 @@
> > +/** @file
> > + Boot UEFI Linux.
> > +
> > + Copyright (c) 2008 - 2013 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/LoadLinuxLib.inf
> > b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> > new file mode 100644
> > index 0000000000..89664f4e42
> > --- /dev/null
> > +++
> > b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> > @@ -0,0 +1,42 @@
> > +## @file
> > +#
> > +# Copyright (c) 2008 - 2012 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > + INF_VERSION = 0x00010005
> > + BASE_NAME = LoadLinuxLib
> > + FILE_GUID = 63CC8497-C9D0-46A8-AC08-49DF92A2FF62
> > + MODULE_TYPE = BASE
> > + VERSION_STRING = 1.0
> > + LIBRARY_CLASS = LoadLinuxLib
> > +
> > +#
> > +# 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
> > + OvmfPkg/OvmfPkg.dec
> > +
> > +[LibraryClasses]
> > + BaseLib
> > + DebugLib
> > + MemoryAllocationLib
> > + BaseMemoryLib
> > +
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKerne
> > l.nasm
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKerne
> > l.nasm
> > new file mode 100644
> > index 0000000000..79e6b8e7ba
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Library/LoadLinuxLib/X64/JumpToKerne
> > l.nasm
> > @@ -0,0 +1,85 @@
> > +; @file
> > +; Copyright (c) 2006 - 2013 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..92aa038cdd
> > --- /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 - 2011 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..e4c3b7ccff
> > --- /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 - 2018 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/SerializeVariablesLib/SerializeVa
> > riablesLib.h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> > riablesLib.h
> > new file mode 100644
> > index 0000000000..7e78cd4b21
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> > riablesLib.h
> > @@ -0,0 +1,33 @@
> > +/** @file
> > + Serialize Variables Library implementation
> > +
> > + Copyright (c) 2009 - 2011 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/SerializeVa
> > riablesLib.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> > riablesLib.inf
> > new file mode 100644
> > index 0000000000..25901192b2
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Library/SerializeVariablesLib/SerializeVa
> > riablesLib.inf
> > @@ -0,0 +1,36 @@
> > +## @file
> > +# Serialize Variables Library implementation
> > +#
> > +# This library serializes and deserializes UEFI variables
> > +#
> > +# Copyright (c) 2006 - 2018 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
> > + OvmfPkg/OvmfPkg.dec
> > +
> > +[LibraryClasses]
> > + BaseLib
> > + BaseMemoryLib
> > + DebugLib
> > + MemoryAllocationLib
> > + UefiBootServicesTableLib
> > + UefiRuntimeServicesTableLib
> > +
> > diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> > new file mode 100644
> > index 0000000000..63b5e52575
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.h
> > @@ -0,0 +1,37 @@
> > +/** @file
> > + This driver effectuates OVMF's 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/PlatformDxe/Platform.inf
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.inf
> > new file mode 100644
> > index 0000000000..804ab59610
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.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 = PlatformDxe
> > + 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/SimicsOpenBoardPkg.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
> > + gSimicsX58PlatformConfigGuid
> > +
> > +[Depex]
> > + gEfiHiiConfigRoutingProtocolGuid AND
> > + gEfiHiiDatabaseProtocolGuid AND
> > + gEfiVariableArchProtocolGuid AND
> > + gEfiVariableWriteArchProtocolGuid
> > diff --git a/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/Platform.uni
> > new file mode 100644
> > index 0000000000..6d68cbeb4f
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/PlatformDxe/PlatformConfig.h
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformConfig.h
> > new file mode 100644
> > index 0000000000..d3f041ddea
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/PlatformDxe/PlatformForms.vfr
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/PlatformForms.vfr
> > new file mode 100644
> > index 0000000000..1c02565ebb
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformDxe/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/SimicsX58PlatformConfig.h>
> > +#include "Platform.h"
> > +
> > +formset
> > + guid = SIMICSX58_PLATFORM_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 = SIMICSX58_PLATFORM_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/PlatformPei/Cmos.h
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
> > new file mode 100644
> > index 0000000000..616d2d74cb
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Cmos.h
> > @@ -0,0 +1,50 @@
> > +/** @file
> > + PC/AT CMOS access routines
> > +
> > + Copyright (c) 2006 - 2009 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/PlatformPei/Platform.h
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
> > new file mode 100644
> > index 0000000000..5b1a9b5f57
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/Platform.h
> > @@ -0,0 +1,93 @@
> > +/** @file
> > + Platform PEI module include file.
> > +
> > + Copyright (c) 2006 - 2016 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
> > + );
> > +
> > +EFI_STATUS
> > +PeiFvInitialization (
> > + 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/PlatformPei/PlatformPei.inf
> > b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
> > new file mode 100644
> > index 0000000000..eb8048c655
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/PlatformPei/PlatformPei.inf
> > @@ -0,0 +1,109 @@
> > +## @file
> > +# Platform PEI driver
> > +#
> > +# This module provides platform specific function to detect boot mode.
> > +# Copyright (c) 2006 - 2018 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > + INF_VERSION = 0x00010005
> > + BASE_NAME = PlatformPei
> > + 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
> > + Fv.c
> > + MemDetect.c
> > + Platform.c
> > +
> > +[Packages]
> > + MdePkg/MdePkg.dec
> > + MdeModulePkg/MdeModulePkg.dec
> > + UefiCpuPkg/UefiCpuPkg.dec
> > + SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> > + MinPlatformPkg/MinPlatformPkg.dec
> > + OvmfPkg/OvmfPkg.dec
> > +
> > +[Guids]
> > + gEfiMemoryTypeInformationGuid
> > + gEfiSmmPeiSmramMemoryReserveGuid ## CONSUMES
> > +
> > +[LibraryClasses]
> > + BaseLib
> > + DebugLib
> > + HobLib
> > + IoLib
> > + PciLib
> > + PeiResourcePublicationLib
> > + PeiServicesLib
> > + PeiServicesTablePointerLib
> > + PeimEntryPoint
> > + MtrrLib
> > + PcdLib
> > +
> > +[Pcd]
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize
> > + gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> > + gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd
> > + 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/Policy/Library/SiliconPolicyInitLib/Silicon
> > PolicyInitLib.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> > PolicyInitLib.inf
> > new file mode 100644
> > index 0000000000..b9bcb5d2bd
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyInitLib/Silicon
> > PolicyInitLib.inf
> > @@ -0,0 +1,38 @@
> > +## @file
> > +#
> > +# Copyright (c) 2018 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/Sil
> > iconPolicyUpdateLib.inf
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> > iconPolicyUpdateLib.inf
> > new file mode 100644
> > index 0000000000..da165ac947
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/Policy/Library/SiliconPolicyUpdateLib/Sil
> > iconPolicyUpdateLib.inf
> > @@ -0,0 +1,35 @@
> > +## @file
> > +#
> > +# Copyright (c) 2018 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/SimicsOpenBoardPkg.dec
> > b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> > new file mode 100644
> > index 0000000000..17c87aca8c
> > --- /dev/null
> > +++ b/Platform/Intel/SimicsOpenBoardPkg/SimicsOpenBoardPkg.dec
> > @@ -0,0 +1,168 @@
> > +## @file
> > +# EFI/Framework Simics X58 platform
> > +#
> > +# Copyright (c) 2018 Intel Corporation. All rights reserved. <BR>
> > +#
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > + DEC_SPECIFICATION = 0x00010005
> > + PACKAGE_NAME = SimicsX58Pkg
> > + PACKAGE_GUID = E6A03E0D-5944-4dc6-9292-090D609EDD3A
> > + PACKAGE_VERSION = 0.1
> > +
> > +[Includes]
> > + Include
> > +
> > +[Guids]
> > + gSimicsX58PkgTokenSpaceGuid = {0x5b276d20, 0x37d0, 0x4af0, {0x8d,
> > 0x04, 0x47, 0x91, 0x2b, 0x7c, 0x1d, 0x44}}
> > + gSimicsX58PlatformConfigGuid = {0xeed35f57, 0x4ff2, 0x4244, {0xb8,
> 0x3a,
> > 0xea, 0x71, 0x5f, 0xd3, 0x59, 0xa5}}
> > +
> > +[Protocols]
> > + gEfiLegacy8259ProtocolGuid = {0x38321dba, 0x4fe0, 0x4e17, {0x8a,
> > 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1}}
> > + gEfiIsaAcpiProtocolGuid = {0x64a892dc, 0x5561, 0x4536, {0x92,
> 0xc7,
> > 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55}}
> > + gEfiIsaIoProtocolGuid = {0x7ee2bd44, 0x3da0, 0x11d4, {0x9a, 0x38,
> > 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
> > +
> > +[PcdsFixedAtBuild]
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvBase|0x0|UINT32|0
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsPeiMemFvSize|0x0|UINT32|1
> > +
> > gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvBase|0x0|UINT32|0x15
> > +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsDxeMemFvSize|0x0|UINT32|0x16
> > +
> > + #TODO: Remove these two when we integrate new PlatformPei
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvBase|0x00800000|UINT32|2
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsMemFvSize|0x00500000|UINT32|3
> > +
> > + ## 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
> > +
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogBase|0x0|UI
> > NT32|0x8
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageEventLogSize|0x0|UI
> > NT32|0x9
> > +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareFdSize|0x0|UINT32|0xa
> > +
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFirmwareBlockSize|0|UINT32|0xb
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageVariableBase|0x0|UI
> > NT32|0xc
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwSpareBase|0x0|UI
> > NT32|0xd
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsFlashNvStorageFtwWorkingBase|0x0
> > |UINT32|0xe
> > + gSimicsX58PkgTokenSpaceGuid.PcdSimicsFdBaseAddress|0x0|UINT32|0xf
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesBase|0x0|UINT32|0x1
> > 1
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPageTablesSize|0x0|UINT32|0x1
> > 2
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamBase|0x0|UINT32|0
> > x13
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsSecPeiTempRamSize|0x0|UINT32|0x
> > 14
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageBase|0x0|UINT32|0x
> > 18
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsLockBoxStorageSize|0x0|UINT32|0x
> > 19
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT3
> > 2|0x1a
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsDecompressionScratchEnd|0x0|UINT
> > 32|0x1f
> > +
> > +[PcdsDynamic, PcdsDynamicEx]
> > +
> > + # TODO: investigate whether next two Pcds are needed
> > + gSimicsX58PkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|0x28
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEA
> > N|0x10
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdSimicsX58HostBridgePciDevId|0|UINT16|0
> > x1b
> > +
> > + ## The IO port aperture shared by all PCI root bridges.
> > + #
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x23
> > +
> > + ## The 32-bit MMIO aperture shared by all PCI root bridges.
> > + #
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT64|0x24
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT64|0x25
> > +
> > + ## The 64-bit MMIO aperture shared by all PCI root bridges.
> > + #
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x26
> > + gSimicsX58PkgTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x27
> > +
> > +[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|0x1
> > e
> > +
> > +
> > +[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|UIN
> > T16|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|0x0
> > 0000003
> > +
> > + ## 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|0x0
> > 0000004
> > +
> > + ## 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|BOOLE
> > AN|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|0
> > x00000007
> > +
> > + ## 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|0
> > x00000008
> > +
> > +[PcdsFixedAtBuild, PcdsPatchableInModule]
> > + ## FFS filename to find the shell application.
> > + # @Prompt FFS Name of Shell Application
> > + gSimicsX58PkgTokenSpaceGuid.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 |
> > (gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures & 0xF8) == 0
> > +
> >
> gSimicsX58PkgTokenSpaceGuid.PcdIsaBusSupportedFeatures|0x05|UINT8|0x0
> > 0010040
> > \ No newline at end of file
> > diff --git
> >
> a/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> > .h
> >
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> > .h
> > new file mode 100644
> > index 0000000000..38a71a3527
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> > .h
> > @@ -0,0 +1,38 @@
> > +/** @file
> > + This driver installs SMBIOS information for OVMF
> > +
> > + 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..6adaf0beb7
> > --- /dev/null
> > +++
> >
> b/Platform/Intel/SimicsOpenBoardPkg/SmbiosPlatformDxe/SmbiosPlatformDxe
> > .inf
> > @@ -0,0 +1,51 @@
> > +## @file
> > +# This driver installs SMBIOS information for OVMF
> > +#
> > +# 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/SimicsOpenBoardPkg.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 [flat|nested] 37+ messages in thread
end of thread, other threads:[~2019-08-26 23:13 UTC | newest]
Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-08-09 22:46 [edk2-platform patch 0/7] Add Initial QSP MinPlatform Pkg for SIMICS David Wei
2019-08-09 22:46 ` [edk2-platform patch 1/7] SimicsX58SktPkg: Add CPU Pkg for SimicsX58 David Wei
2019-08-15 8:34 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-22 22:31 ` David Wei
2019-08-26 22:48 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 2/7] SimicsICH10Pkg: Add PCH Pkg for SimicsICH10 David Wei
2019-08-13 2:01 ` Nate DeSimone
2019-08-15 8:39 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 16:40 ` David Wei
2019-08-26 22:49 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 3/7] SimicsOpenBoardPkg: Add SimicsOpenBoardPkg and its modules David Wei
2019-08-15 18:35 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 16:57 ` David Wei
2019-08-26 23:13 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 4/7] SimicsOpenBoardPkg: Add DXE driver for Legacy Sio David Wei
2019-08-15 19:01 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 5/7] SimicsOpenBoardPkg: Add Overrides modules for SIMICS QSP Platform David Wei
2019-08-15 19:38 ` Nate DeSimone
2019-08-15 22:28 ` Nate DeSimone
2019-08-15 22:52 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 17:09 ` David Wei
2019-08-26 22:51 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 6/7] SimicsOpenBoardPkg: Add board module for QSP Build tip David Wei
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 17:04 ` David Wei
2019-08-26 22:59 ` Kubacki, Michael A
2019-08-09 22:46 ` [edk2-platform patch 7/7] Platform/Intel: Add build option for SIMICS QSP Platform David Wei
2019-08-15 19:28 ` Nate DeSimone
2019-08-19 23:21 ` Nate DeSimone
2019-08-20 1:04 ` Kubacki, Michael A
2019-08-23 17:06 ` David Wei
2019-08-26 23:00 ` Kubacki, Michael A
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox