diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000000..edd92799cf8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+.vs/
+build/
+nasm-2.13.03/
+nasm-2.13.03-win64.zip
+openssl-1.0.2r-x64_86-win64/
+openssl-1.0.2r-x64_86-win64.zip
+vc140.pdb
+./x64/
+./Release/
+CdeValidationPkg/library/
+./CdeValidationPkg/_CdeMofineLibrary/x64
+./CdeValidationPkg/_CdeMofineLibrary/Win32
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000000..cb09aa77fb8
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,27 @@
+[submodule "blogs/2021-11-14/lib"]
+ path = blogs/2021-11-14/lib
+ url = https://github.com/KilianKegel/toro-C-Library.git
+[submodule "blogs/2021-11-28/lib"]
+ path = blogs/2021-11-28/lib
+ url = https://github.com/KilianKegel/toro-C-Library.git
+[submodule "blogs/2021-11-28/MdePkgInc"]
+ path = blogs/2021-11-28/MdePkgInc
+ url = https://github.com/KilianKegel/MdePkgInc.git
+[submodule "edk2"]
+ path = edk2
+ url = https://github.com/tianocore/edk2.git
+[submodule "edk2-non-osi"]
+ path = edk2-non-osi
+ url = https://github.com/tianocore/edk2-non-osi.git
+[submodule "edk2-platforms"]
+ path = edk2-platforms
+ url = https://github.com/tianocore/edk2-platforms.git
+[submodule "CdePkg"]
+ path = CdePkg
+ url = https://github.com/KilianKegel/CdePkg.git
+[submodule "CdeEmuPkg/RedfishPkg/Library/JsonLib/jansson"]
+ path = CdeEmuPkg/RedfishPkg/Library/JsonLib/jansson
+ url = https://github.com/akheron/jansson.git
+[submodule "blogs/2022-01-16/Visual-ACPICA-for-UEFI-Shell"]
+ path = blogs/2022-01-16/Visual-ACPICA-for-UEFI-Shell
+ url = https://github.com/KilianKegel/Visual-ACPICA-for-UEFI-Shell.git
diff --git a/CdeEmuPkg/EmulatorPkg.dsc b/CdeEmuPkg/EmulatorPkg.dsc
new file mode 100644
index 00000000000..02e525f8b22
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg.dsc
@@ -0,0 +1,546 @@
+## @file
+# UEFI/PI Emulation Platform with UEFI HII interface supported.
+#
+# The Emulation Platform can be used to debug individual modules, prior to creating
+# a real platform. This also provides an example for how an DSC is created.
+#
+# Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.
+# Copyright (c) Microsoft Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ PLATFORM_NAME = EmulatorPkg
+ PLATFORM_GUID = 05FD064D-1073-E844-936C-A0E16317107D
+ PLATFORM_VERSION = 0.3
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/Emulator$(ARCH)
+
+ SUPPORTED_ARCHITECTURES = X64|IA32
+ BUILD_TARGETS = DEBUG|RELEASE|NOOPT
+ SKUID_IDENTIFIER = DEFAULT
+ FLASH_DEFINITION = EmulatorPkg.fdf
+
+
+ #
+ # Network definition
+ #
+ DEFINE NETWORK_SNP_ENABLE = FALSE
+ DEFINE NETWORK_IP6_ENABLE = FALSE
+ DEFINE NETWORK_TLS_ENABLE = FALSE
+ DEFINE NETWORK_HTTP_BOOT_ENABLE = FALSE
+ DEFINE NETWORK_HTTP_ENABLE = FALSE
+ DEFINE NETWORK_ISCSI_ENABLE = FALSE
+ DEFINE SECURE_BOOT_ENABLE = FALSE
+
+ #
+ # Redfish definition
+ #
+ DEFINE REDFISH_ENABLE = TRUE
+
+[SkuIds]
+ 0|DEFAULT
+
+!include MdePkg/MdeLibs.dsc.inc
+
+[LibraryClasses]
+ #
+ # Entry point
+ #
+ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+ DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+ #
+ # Basic
+ #
+ #KGDebug
+ CdeLib|CdePkg\CdeLib\CdeLib.inf
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
+
+ #
+ # UEFI & PI
+ #
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+ UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+ SmbiosLib|EmulatorPkg/Library/SmbiosLib/SmbiosLib.inf
+
+ #
+ # Generic Modules
+ #
+ UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+ BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+ UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+ BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
+ SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+ CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+ SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+ SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+ #
+ # Platform
+ #
+ PlatformBootManagerLib|EmulatorPkg/Library/PlatformBmLib/PlatformBmLib.inf
+ KeyMapLib|EmulatorPkg/Library/KeyMapLibNull/KeyMapLibNull.inf
+ !if $(REDFISH_ENABLE) == TRUE
+ RedfishPlatformHostInterfaceLib|EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.inf
+ RedfishPlatformCredentialLib|EmulatorPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCredentialLib.inf
+ !endif
+ #
+ # Misc
+ #
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+ DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+ PeiServicesTablePointerLib|EmulatorPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointerLibMagicPage.inf
+ DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
+ LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+ CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
+ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+ VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+ VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
+ VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+ SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf
+ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
+ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+ PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
+ AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+ SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+ SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
+!else
+ AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+!endif
+
+[LibraryClasses.common.SEC]
+ PeiServicesLib|EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ PeCoffGetEntryPointLib|EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf
+ PeCoffExtraActionLib|EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf
+ SerialPortLib|EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
+ PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+ TimerLib|EmulatorPkg/Library/PeiTimerLib/PeiTimerLib.inf
+
+[LibraryClasses.common.USER_DEFINED, LibraryClasses.common.BASE]
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf
+ ThunkPpiList|EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf
+ ThunkProtocolList|EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+ PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf
+ PeiServicesLib|EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf
+
+
+[LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+ PeCoffGetEntryPointLib|EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf
+ PeCoffExtraActionLib|EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+ SerialPortLib|EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+ TimerLib|EmulatorPkg/Library/PeiTimerLib/PeiTimerLib.inf
+
+[LibraryClasses.common.PEI_CORE]
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+[LibraryClasses.common.PEIM]
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+ HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+ MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+ PeCoffExtraActionLib|EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ TimerLib|EmulatorPkg/Library/DxeCoreTimerLib/DxeCoreTimerLib.inf
+ EmuThunkLib|EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.inf
+
+[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION]
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+!endif
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.UEFI_APPLICATION]
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+ EmuThunkLib|EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.inf
+ PeCoffExtraActionLib|EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+ TimerLib|EmulatorPkg/Library/DxeTimerLib/DxeTimerLib.inf
+
+[PcdsFeatureFlag]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE
+# gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables|FALSE
+
+[PcdsFixedAtBuild]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000040
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x0f
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizeNonPopulateCapsule|0x0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizePopulateCapsule|0x0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
+
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareFdSize|0x002a0000
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareBlockSize|0x10000
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareVolume|L"../FV/FV_RECOVERY.fd"
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+ gEfiSecurityPkgTokenSpaceGuid.PcdUserPhysicalPresence|TRUE
+!endif
+
+ gEmulatorPkgTokenSpaceGuid.PcdEmuMemorySize|L"64!64"
+
+ # Change PcdBootManagerMenuFile to UiApp
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+
+#define BOOT_WITH_FULL_CONFIGURATION 0x00
+#define BOOT_WITH_MINIMAL_CONFIGURATION 0x01
+#define BOOT_ASSUMING_NO_CONFIGURATION_CHANGES 0x02
+#define BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS 0x03
+#define BOOT_WITH_DEFAULT_SETTINGS 0x04
+#define BOOT_ON_S4_RESUME 0x05
+#define BOOT_ON_S5_RESUME 0x06
+#define BOOT_ON_S2_RESUME 0x10
+#define BOOT_ON_S3_RESUME 0x11
+#define BOOT_ON_FLASH_UPDATE 0x12
+#define BOOT_IN_RECOVERY_MODE 0x20
+ gEmulatorPkgTokenSpaceGuid.PcdEmuBootMode|0
+
+ gEmulatorPkgTokenSpaceGuid.PcdEmuApCount|L"1"
+
+ # For a CD-ROM/DVD use L"diag.dmg:RO:2048"
+ gEmulatorPkgTokenSpaceGuid.PcdEmuVirtualDisk|L"disk.dmg:FW"
+ gEmulatorPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window"
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFileSystem|L"."
+ gEmulatorPkgTokenSpaceGuid.PcdEmuSerialPort|L"/dev/ttyS0"
+ gEmulatorPkgTokenSpaceGuid.PcdEmuNetworkInterface|L"en0"
+
+ gEmulatorPkgTokenSpaceGuid.PcdEmuCpuModel|L"Intel(R) Processor Model"
+ gEmulatorPkgTokenSpaceGuid.PcdEmuCpuSpeed|L"3000"
+
+ # 0-PCANSI, 1-VT100, 2-VT00+, 3-UTF8, 4-TTYTERM
+ gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|1
+
+!if $(REDFISH_ENABLE) == TRUE
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceDevicePath.DevicePathMatchMode|DEVICE_PATH_MATCH_MAC_NODE
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceDevicePath.DevicePathNum|1
+ #
+ # Below is the MAC address of network adapter on EDK2 Emulator platform.
+ # You can use ifconfig under EFI shell to get the MAC address of network adapter on EDK2 Emulator platform.
+ #
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceDevicePath.DevicePath|{DEVICE_PATH("MAC(000000000000,0x1)")}
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceAccessModeInBand|False
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDiscoverAccessModeInBand|False
+!endif
+[PcdsDynamicDefault.common.DEFAULT]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
+
+[PcdsDynamicHii.common.DEFAULT]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|L"Setup"|gEmuSystemConfigGuid|0x0|80
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|L"Setup"|gEmuSystemConfigGuid|0x4|25
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|10
+
+[Components]
+!if "IA32" in $(ARCH) || "X64" in $(ARCH)
+ !if "MSFT" in $(FAMILY) || $(WIN_HOST_BUILD) == TRUE
+ ##
+ # Emulator, OS WIN application
+ # CLANGPDB is cross OS tool chain. It depends on WIN_HOST_BUILD flag
+ # to build WinHost application.
+ ##
+ #EmulatorPkg/Win/Host/WinHost.inf
+ CdeEmuPkg/Win/Host/WinHost.inf
+ !else
+ ##
+ # Emulator, OS POSIX application
+ ##
+ EmulatorPkg/Unix/Host/Host.inf
+ !endif
+!endif
+
+!ifndef $(SKIP_MAIN_BUILD)
+ #
+ # Generic SEC
+ #
+ EmulatorPkg/Sec/Sec.inf
+
+ ##
+ # PEI Phase modules
+ ##
+ MdeModulePkg/Core/Pei/PeiMain.inf
+
+ #KGDebug start
+ CdePkg/CdeServices/CdeServicesPei.inf
+ CdePkg\CdeWelcome\buildPRE.inf
+ CdePkg/CdeLoadOptionsPei/CdeLoadOptionsPei.inf
+
+ #CdeValidationPkg/HOSTED_ENV/argcv/buildPEI.inf
+ #CdeValidationPkg/SYSTEM_IF/systeminterfacePEI/buildPEI.inf
+ #CdeValidationPkg/template/buildPEI.inf
+ #CdeValidationPkg/TIME_H/clock/buildPEI.inf
+ #CdeValidationPkg/TIME_H/timehfunctions/buildPEI.inf
+ #CdeValidationPkg/STRING_H/stringhfunctions/buildPEI.inf
+ #CdeValidationPkg/WCHAR_H/wcharhfunctions/buildPEI.inf
+ #CdeValidationPkg/STDIO_H/stdiohfunctions/buildPEI.inf
+ #CdeValidationPkg/STDLIB_H/stdlibhfunctions/buildPEI.inf
+ #CdeValidationPkg/CTYPE_H/ctypehfunctions/buildPEI.inf
+ #CdeValidationPkg/WCTYPE_H/wctypehfunctions/buildPEI.inf
+ #CdeValidationPkg/ASSERT_H/asserthfunctions/buildPEI.inf
+ #CdeValidationPkg/LOCALE_H/localehfunctions/buildPEI.inf
+#KGDebug end
+
+ MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+ MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+ MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+
+ EmulatorPkg/BootModePei/BootModePei.inf
+ MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+ MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+ EmulatorPkg/AutoScanPei/AutoScanPei.inf
+ EmulatorPkg/FirmwareVolumePei/FirmwareVolumePei.inf
+ EmulatorPkg/FlashMapPei/FlashMapPei.inf
+ EmulatorPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf
+ MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+ ##
+ # DXE Phase modules
+ ##
+ MdeModulePkg/Core/Dxe/DxeMain.inf {
+
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+ SerialPortLib|EmulatorPkg/Library/DxeEmuStdErrSerialPortLib/DxeEmuStdErrSerialPortLib.inf
+ DxeEmuLib|EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.inf
+ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ }
+ #KGDebug
+ CdePkg\CdeServices\CdeServicesDxe.inf
+ CdePkg\CdeWelcome\buildDXE.inf
+ CdePkg/CdeLoadOptionsDxe/CdeLoadOptionsDxe.inf
+
+ #CdeValidationPkg/HOSTED_ENV/argcv/buildDXE.inf
+ #CdeValidationPkg/SYSTEM_IF/systeminterfaceDXE/buildDXE.inf
+ #CdeValidationPkg/template/buildDXE.inf
+ #CdeValidationPkg/TIME_H/clock/buildDXE.inf
+ #CdeValidationPkg/TIME_H/timehfunctions/buildDXE.inf
+ #CdeValidationPkg/STRING_H/stringhfunctions/buildDXE.inf
+ #CdeValidationPkg/WCHAR_H/wcharhfunctions/buildDXE.inf
+ #CdeValidationPkg/STDIO_H/stdiohfunctions/buildDXE.inf
+ #CdeValidationPkg/STDLIB_H/stdlibhfunctions/buildDXE.inf
+ #CdeValidationPkg/CTYPE_H/ctypehfunctions/buildDXE.inf
+ #CdeValidationPkg/WCTYPE_H/wctypehfunctions/buildDXE.inf
+ #CdeValidationPkg/ASSERT_H/asserthfunctions/buildDXE.inf
+ #CdeValidationPkg/LOCALE_H/localehfunctions/buildDXE.inf
+ #KGDebug
+
+ MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+
+ MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+ MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf {
+
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+ SerialPortLib|EmulatorPkg/Library/DxeEmuStdErrSerialPortLib/DxeEmuStdErrSerialPortLib.inf
+ }
+
+ MdeModulePkg/Universal/Metronome/Metronome.inf
+ EmulatorPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf
+ EmulatorPkg/ResetRuntimeDxe/Reset.inf
+ MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ EmulatorPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+
+ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+!endif
+ }
+ MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+ MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+ EmulatorPkg/EmuThunkDxe/EmuThunk.inf
+ EmulatorPkg/CpuRuntimeDxe/Cpu.inf
+ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ EmulatorPkg/PlatformSmbiosDxe/PlatformSmbiosDxe.inf
+ EmulatorPkg/TimerDxe/Timer.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+
+ NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+ }
+ MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+ MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+ MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ MdeModulePkg/Universal/SerialDxe/SerialDxe.inf {
+
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ SerialPortLib|EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf
+ }
+
+ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+!if "XCODE5" not in $(TOOL_CHAIN_TAG)
+ MdeModulePkg/Logo/LogoDxe.inf
+!endif
+ MdeModulePkg/Universal/LoadFileOnFv2/LoadFileOnFv2.inf
+ MdeModulePkg/Application/UiApp/UiApp.inf {
+
+ NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+ NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+ NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+ }
+ MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
+
+ MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ #{
+ #
+ # NULL|EmulatorPkg/Library/DevicePathTextLib/DevicePathTextLib.inf
+ #}
+
+ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+ MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+ EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf
+ EmulatorPkg/EmuGopDxe/EmuGopDxe.inf
+ EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf
+ EmulatorPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf
+ EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf
+
+ MdeModulePkg/Application/HelloWorld/HelloWorld.inf
+
+ MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+ MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+ MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+# MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf {
+ CdeEmuPkg/MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf {
+
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+
+ FatPkg/EnhancedFatDxe/Fat.inf
+
+!if "XCODE5" not in $(TOOL_CHAIN_TAG)
+ ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf {
+
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ }
+!endif
+ ShellPkg/Application/Shell/Shell.inf {
+
+ ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+ 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/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+ HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+ OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+ SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+# SafeBlockIoLib|ShellPkg/Library/SafeBlockIoLib/SafeBlockIoLib.inf
+# SafeOpenProtocolLib|ShellPkg/Library/SafeOpenProtocolLib/SafeOpenProtocolLib.inf
+ BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+
+
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+ }
+
+!endif
+
+!include NetworkPkg/Network.dsc.inc
+
+!if $(REDFISH_ENABLE) == TRUE
+ EmulatorPkg/Application/RedfishPlatformConfig/RedfishPlatformConfig.inf
+!endif
+!include RedfishPkg/Redfish.dsc.inc
+[BuildOptions]
+ #
+ # Disable deprecated APIs.
+ #
+ *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
+
+ MSFT:DEBUG_*_*_CC_FLAGS = /Od /Oy-
+ MSFT:NOOPT_*_*_CC_FLAGS = /Od /Oy-
+ GCC:DEBUG_CLANGPDB_*_CC_FLAGS =-O0 -Wno-unused-command-line-argument -Wno-incompatible-pointer-types -Wno-enum-conversion -Wno-incompatible-pointer-types -Wno-sometimes-uninitialized -Wno-constant-conversion -Wno-main-return-type
+
+ MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096 /FILEALIGN:4096 /SUBSYSTEM:CONSOLE
+ MSFT:DEBUG_*_*_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /BASE:0x10000
+ MSFT:NOOPT_*_*_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /BASE:0x10000
+!if $(WIN_HOST_BUILD) == TRUE
+ #
+ # CLANGPDB tool chain depends on WIN_HOST_BUILD flag to generate the windows application.
+ #
+ GCC:*_CLANGPDB_*_DLINK_FLAGS = /ALIGN:4096 /FILEALIGN:4096 /SUBSYSTEM:CONSOLE
+ GCC:DEBUG_CLANGPDB_*_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /BASE:0x10000
+ GCC:NOOPT_CLANGPDB_*_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /BASE:0x10000
+!endif
diff --git a/CdeEmuPkg/EmulatorPkg.fdf b/CdeEmuPkg/EmulatorPkg.fdf
new file mode 100644
index 00000000000..54dbfe2019d
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg.fdf
@@ -0,0 +1,380 @@
+## @file
+# This is Emulator FDF file with UEFI HII features enabled
+#
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2009 - 2011, Apple Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+[FD.Fv_Recovery]
+#
+# In OS X PEIMs are really XIP, so we need to make this address match the malloced
+# buffer for the FD (0x41000000). If this address does not match the FV will get
+# relocated in place (works, but not a great idea).
+#
+BaseAddress = 0x102000000|gEmulatorPkgTokenSpaceGuid.PcdEmuFdBaseAddress #The base address of the FLASH Device.
+Size = 0x005a0000|gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareFdSize #The size in bytes of the FLASH Device
+ErasePolarity = 1
+BlockSize = 0x10000
+NumBlocks = 0x5a
+
+0x00000000|0x00580000
+gEmulatorPkgTokenSpaceGuid.PcdEmuFlashFvRecoveryBase|gEmulatorPkgTokenSpaceGuid.PcdEmuFlashFvRecoverySize
+FV = FvRecovery
+
+0x00580000|0x0000c000
+gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageVariableBase|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: 0x20000
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ # Signature "_FVH" #Attributes
+ 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+ # HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+ 0x48, 0x00, 0x36, 0x09, 0x00, 0x00, 0x00, 0x02,
+ # Blockmap[0]: 2 Blocks * 0x10000 Bytes / Block
+ 0x02, 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) == FALSE
+ #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,
+!else
+ # 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,
+!endif
+ #Size: 0xc000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0xBFB8
+ # This can speed up the Variable Dispatch a bit.
+ 0xB8, 0xBF, 0x00, 0x00,
+ #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+ 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x0058c000|0x00002000
+#NV_EVENT_LOG
+gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogBase|gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogSize
+
+0x0058e000|0x00002000
+gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwWorkingBase|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
+}
+
+0x00590000|0x00010000
+#NV_FTW_SPARE
+gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+[FV.FvRecovery]
+FvNameGuid = 6D99E806-3D38-42c2-A095-5F4300BFD7DC
+FvAlignment = 16 #FV alignment and FV attributes setting.
+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
+
+#
+# PEI Phase modules
+#
+
+#
+# PEI Apriori file example, more PEIM module added later.
+#
+APRIORI PEI {
+ INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+ INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+ INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+ }
+APRIORI DXE {
+ INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+ INF MdeModulePkg/Universal/Metronome/Metronome.inf
+ }
+#KGDebug
+INF CdePkg/CdeServices/CdeServicesPei.inf
+INF CdePkg/CdeWelcome/buildPRE.inf
+INF CdePkg/CdeLoadOptionsPei/CdeLoadOptionsPei.inf
+
+#INF CdeValidationPkg/HOSTED_ENV/argcv/buildPEI.inf
+#INF CdeValidationPkg/SYSTEM_IF/systeminterfacePEI/buildPEI.inf
+#INF CdeValidationPkg/template/buildPEI.inf
+#INF CdeValidationPkg/TIME_H/timehfunctions/buildPEI.inf
+#INF CdeValidationPkg/STRING_H/stringhfunctions/buildPEI.inf
+#INF CdeValidationPkg/WCHAR_H/wcharhfunctions/buildPEI.inf
+#INF CdeValidationPkg/STDIO_H/stdiohfunctions/buildPEI.inf
+#INF CdeValidationPkg/STDLIB_H/stdlibhfunctions/buildPEI.inf
+#INF CdeValidationPkg/CTYPE_H/ctypehfunctions/buildPEI.inf
+#INF CdeValidationPkg/WCTYPE_H/wctypehfunctions/buildPEI.inf
+#INF CdeValidationPkg/ASSERT_H/asserthfunctions/buildPEI.inf
+#INF CdeValidationPkg/LOCALE_H/localehfunctions/buildPEI.inf
+#INF CdeValidationPkg/TIME_H/clock/buildPEI.inf
+#KGDebug
+
+INF EmulatorPkg/Sec/Sec.inf
+INF MdeModulePkg/Core/Pei/PeiMain.inf
+INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+INF EmulatorPkg/BootModePei/BootModePei.inf
+INF EmulatorPkg/AutoScanPei/AutoScanPei.inf
+INF EmulatorPkg/FirmwareVolumePei/FirmwareVolumePei.inf
+INF EmulatorPkg/FlashMapPei/FlashMapPei.inf
+INF EmulatorPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf
+INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+#
+# DXE Phase modules
+#
+#KGDebug
+INF CdePkg/CdeServices/CdeServicesDxe.inf
+INF CdePkg/CdeWelcome/buildDXE.inf
+INF CdePkg/CdeLoadOptionsDxe/CdeLoadOptionsDxe.inf
+
+#INF CdeValidationPkg/HOSTED_ENV/argcv/buildDXE.inf
+#INF CdeValidationPkg/SYSTEM_IF/systeminterfaceDXE/buildDXE.inf
+#INF CdeValidationPkg/template/buildDXE.inf
+#INF CdeValidationPkg/TIME_H/timehfunctions/buildDXE.inf
+#INF CdeValidationPkg/STRING_H/stringhfunctions/buildDXE.inf
+#INF CdeValidationPkg/WCHAR_H/wcharhfunctions/buildDXE.inf
+#INF CdeValidationPkg/STDIO_H/stdiohfunctions/buildDXE.inf
+#INF CdeValidationPkg/STDLIB_H/stdlibhfunctions/buildDXE.inf
+#INF CdeValidationPkg/CTYPE_H/ctypehfunctions/buildDXE.inf
+#INF CdeValidationPkg/WCTYPE_H/wctypehfunctions/buildDXE.inf
+#INF CdeValidationPkg/ASSERT_H/asserthfunctions/buildDXE.inf
+#INF CdeValidationPkg/LOCALE_H/localehfunctions/buildDXE.inf
+#INF CdeValidationPkg/TIME_H/clock/buildDXE.inf
+#KGDebug
+
+INF MdeModulePkg/Core/Dxe/DxeMain.inf
+INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+INF MdeModulePkg/Universal/Metronome/Metronome.inf
+INF EmulatorPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf
+INF EmulatorPkg/ResetRuntimeDxe/Reset.inf
+INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+INF EmulatorPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+INF EmulatorPkg/EmuThunkDxe/EmuThunk.inf
+INF EmulatorPkg/CpuRuntimeDxe/Cpu.inf
+INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+INF EmulatorPkg/PlatformSmbiosDxe/PlatformSmbiosDxe.inf
+INF EmulatorPkg/TimerDxe/Timer.inf
+INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+
+INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+
+INF EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf
+INF EmulatorPkg/EmuGopDxe/EmuGopDxe.inf
+INF EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf
+INF EmulatorPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf
+INF EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf
+
+INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+INF MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+!if "XCODE5" not in $(TOOL_CHAIN_TAG)
+INF MdeModulePkg/Logo/LogoDxe.inf
+!endif
+INF MdeModulePkg/Universal/LoadFileOnFv2/LoadFileOnFv2.inf
+INF RuleOverride = UI MdeModulePkg/Application/UiApp/UiApp.inf
+INF MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
+#INF MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf
+INF CdeEmuPkg/MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf
+
+#
+# Secure Boot Key Enroll
+#
+!if $(SECURE_BOOT_ENABLE) == TRUE
+INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+
+#
+# Network stack drivers
+#
+!if $(NETWORK_SUPPORT)
+INF EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf
+!endif
+!include NetworkPkg/Network.fdf.inc
+
+#
+# EFI Redfish drivers
+#
+!include RedfishPkg/Redfish.fdf.inc
+
+INF FatPkg/EnhancedFatDxe/Fat.inf
+
+!if "XCODE5" not in $(TOOL_CHAIN_TAG)
+INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
+!endif
+INF ShellPkg/Application/Shell/Shell.inf
+
+[Rule.Common.SEC]
+ FILE SEC = $(NAMED_GUID) {
+ PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING ="$(MODULE_NAME)" Optional
+ VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+
+[Rule.Common.PEI_CORE]
+ FILE PEI_CORE = $(NAMED_GUID) {
+ PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING ="$(MODULE_NAME)" Optional
+ VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.PEIM]
+ FILE PEIM = $(NAMED_GUID) {
+ PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.DXE_CORE]
+ FILE DXE_CORE = $(NAMED_GUID) {
+ COMPRESS PI_STD {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+ }
+
+[Rule.Common.UEFI_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ COMPRESS PI_STD {
+ GUIDED {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+ }
+ }
+
+[Rule.Common.DXE_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ COMPRESS PI_STD {
+ GUIDED {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+ }
+ }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ COMPRESS PI_STD {
+ GUIDED {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+ }
+ }
+
+[Rule.Common.UEFI_APPLICATION]
+ FILE APPLICATION = $(NAMED_GUID) {
+ COMPRESS PI_STD {
+ GUIDED {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+ }
+ }
+
+[Rule.Common.UEFI_APPLICATION.UI]
+ FILE APPLICATION = $(NAMED_GUID) {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="Enter Setup"
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional |.depex
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+ FILE APPLICATION = $(NAMED_GUID) {
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+#KGDebug
+[Rule.Common.PEIM.BINARY]
+ FILE PEIM = $(NAMED_GUID) {
+ PEI_DEPEX PEI_DEPEX Optional |.depex
+ PE32 PE32 Align = Auto |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.DXE_DRIVER.BINARY]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional |.depex
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
diff --git a/CdeEmuPkg/EmulatorPkg/Application/RedfishPlatformConfig/RedfishPlatformConfig.c b/CdeEmuPkg/EmulatorPkg/Application/RedfishPlatformConfig/RedfishPlatformConfig.c
new file mode 100644
index 00000000000..1500dc034fe
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Application/RedfishPlatformConfig/RedfishPlatformConfig.c
@@ -0,0 +1,298 @@
+/** @file
+ The implementation for Redfish Platform Configuration application.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+UINTN Argc;
+CHAR16 **Argv;
+
+/**
+
+ This function parse application ARG.
+
+ @return Status
+**/
+EFI_STATUS
+GetArg (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters;
+
+ Status = gBS->HandleProtocol (
+ gImageHandle,
+ &gEfiShellParametersProtocolGuid,
+ (VOID**)&ShellParameters
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Argc = ShellParameters->Argc;
+ Argv = ShellParameters->Argv;
+ return EFI_SUCCESS;
+}
+
+/**
+
+ This function print the help message.
+
+**/
+VOID
+PrintHelp (
+ VOID
+ )
+{
+ Print (L"\n");
+ Print (L"Format (Only Ipv4 Address is supported):\n");
+ Print (L"RedfishPlatformConfig.efi -s HostIpAddress HostIpMask RedfishServiceIpAddress RedfishServiceIpMask RedfishServiceIpPort\n");
+ Print (L"OR:\n");
+ Print (L"RedfishPlatformConfig.efi -a RedfishServiceIpAddress RedfishServiceIpMask RedfishServiceIpPort\n");
+ Print (L"\n");
+}
+
+/**
+ The user Entry Point for Application. The user code starts with this function
+ as the real entry point for the application.
+
+ @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
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ RETURN_STATUS ReturnStatus;
+
+ UINT8 HostIpAssignmentType;
+ EFI_IPv4_ADDRESS HostIpAddress;
+ EFI_IPv4_ADDRESS HostIpMask;
+ EFI_IPv4_ADDRESS RedfishServiceIpAddress;
+ EFI_IPv4_ADDRESS RedfishServiceIpMask;
+ UINTN RedfishServiceIpPort;
+
+ Status = GetArg();
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Format is like :
+ // RedfishPlatformConfig.efi -s HostIpAddress HostIpMask RedfishServiceIpAddress RedfishServiceIpMask RedfishServiceIpPort
+ // RedfishPlatformConfig.efi -a RedfishServiceIpAddress RedfishServiceIpMask RedfishServiceIpPort
+ //
+ if (Argc != 7 && Argc != 5) {
+
+ PrintHelp();
+ return EFI_UNSUPPORTED;
+ }
+
+ if (StrCmp(Argv[1], L"-s") == 0) {
+
+ HostIpAssignmentType = 1;
+
+ Status = NetLibStrToIp4 (Argv[2], &HostIpAddress);
+ if (EFI_ERROR (Status)) {
+ PrintHelp();
+ return Status;
+ }
+ Status = NetLibStrToIp4 (Argv[3], &HostIpMask);
+ if (EFI_ERROR (Status)) {
+ PrintHelp();
+ return Status;
+ }
+ Status = NetLibStrToIp4 (Argv[4], &RedfishServiceIpAddress);
+ if (EFI_ERROR (Status)) {
+ PrintHelp();
+ return Status;
+ }
+ Status = NetLibStrToIp4 (Argv[5], &RedfishServiceIpMask);
+ if (EFI_ERROR (Status)) {
+ PrintHelp();
+ return Status;
+ }
+ ReturnStatus = StrDecimalToUintnS (Argv[6], NULL, &RedfishServiceIpPort);
+ if (RETURN_ERROR (ReturnStatus)) {
+ PrintHelp();
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ L"HostIpAssignmentType",
+ &gEmuRedfishServiceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (UINT8),
+ &HostIpAssignmentType
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ L"HostIpAddress",
+ &gEmuRedfishServiceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (EFI_IPv4_ADDRESS),
+ &HostIpAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ L"HostIpMask",
+ &gEmuRedfishServiceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (EFI_IPv4_ADDRESS),
+ &HostIpMask
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ L"RedfishServiceIpAddress",
+ &gEmuRedfishServiceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (EFI_IPv4_ADDRESS),
+ &RedfishServiceIpAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ L"RedfishServiceIpMask",
+ &gEmuRedfishServiceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (EFI_IPv4_ADDRESS),
+ &RedfishServiceIpMask
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ L"RedfishServiceIpPort",
+ &gEmuRedfishServiceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (UINT16),
+ &RedfishServiceIpPort
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Print (L"\n");
+ Print (L"HostIpAssignmentType is Static!\n");
+ Print (L"HostIpAddress: %s has been set Successfully!\n", Argv[2]);
+ Print (L"HostIpMask: %s has been set Successfully!\n", Argv[3]);
+ Print (L"RedfishServiceIpAddress: %s has been set Successfully!\n", Argv[4]);
+ Print (L"RedfishServiceIpMask: %s has been set Successfully!\n", Argv[5]);
+ Print (L"RedfishServiceIpPort: %s has been set Successfully!\n", Argv[6]);
+ Print (L"Please Restart!\n");
+
+ } else if (StrCmp(Argv[1], L"-a") == 0) {
+
+ HostIpAssignmentType = 3;
+
+ Status = NetLibStrToIp4 (Argv[2], &RedfishServiceIpAddress);
+ if (EFI_ERROR (Status)) {
+ PrintHelp();
+ return Status;
+ }
+ Status = NetLibStrToIp4 (Argv[3], &RedfishServiceIpMask);
+ if (EFI_ERROR (Status)) {
+ PrintHelp();
+ return Status;
+ }
+ ReturnStatus = StrDecimalToUintnS (Argv[4], NULL, &RedfishServiceIpPort);
+ if (RETURN_ERROR (ReturnStatus)) {
+ PrintHelp();
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ L"HostIpAssignmentType",
+ &gEmuRedfishServiceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (UINT8),
+ &HostIpAssignmentType
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ L"RedfishServiceIpAddress",
+ &gEmuRedfishServiceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (EFI_IPv4_ADDRESS),
+ &RedfishServiceIpAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ L"RedfishServiceIpMask",
+ &gEmuRedfishServiceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (EFI_IPv4_ADDRESS),
+ &RedfishServiceIpMask
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gRT->SetVariable (
+ L"RedfishServiceIpPort",
+ &gEmuRedfishServiceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (UINT16),
+ &RedfishServiceIpPort
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Print (L"\n");
+ Print (L"HostIpAssignmentType is Auto!\n");
+ Print (L"RedfishServiceIpAddress: %s has been set Successfully!\n", Argv[2]);
+ Print (L"RedfishServiceIpMask: %s has been set Successfully!\n", Argv[3]);
+ Print (L"RedfishServiceIpPort: %s has been set Successfully!\n", Argv[4]);
+ Print (L"Please Restart!\n");
+ } else if (StrCmp(Argv[1], L"-h") == 0 || StrCmp(Argv[1], L"-help") == 0) {
+
+ PrintHelp();
+ } else {
+
+ PrintHelp();
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/Application/RedfishPlatformConfig/RedfishPlatformConfig.inf b/CdeEmuPkg/EmulatorPkg/Application/RedfishPlatformConfig/RedfishPlatformConfig.inf
new file mode 100644
index 00000000000..cc2e0c2337c
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Application/RedfishPlatformConfig/RedfishPlatformConfig.inf
@@ -0,0 +1,43 @@
+## @file
+# Sample UEFI Application Reference EDKII Module.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001000b
+ BASE_NAME = RedfishPlatformConfig
+ FILE_GUID = C02B67BB-3D19-4ACC-A080-1BDB575F8F36
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = UefiMain
+
+[Sources]
+ RedfishPlatformConfig.c
+
+[Packages]
+ EmulatorPkg/EmulatorPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ NetworkPkg/NetworkPkg.dec
+ RedfishPkg/RedfishPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ NetLib
+ UefiApplicationEntryPoint
+ UefiLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+
+[Protocols]
+ gEfiShellParametersProtocolGuid ## CONSUMES
+ gEfiShellProtocolGuid ## CONSUMES
+
+[Guids]
+ gEmuRedfishServiceGuid
diff --git a/CdeEmuPkg/EmulatorPkg/AutoScanPei/AutoScanPei.c b/CdeEmuPkg/EmulatorPkg/AutoScanPei/AutoScanPei.c
new file mode 100644
index 00000000000..214a279db62
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/AutoScanPei/AutoScanPei.c
@@ -0,0 +1,103 @@
+/*++ @file
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiPei.h"
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+EFI_STATUS
+EFIAPI
+PeimInitializeAutoScanPei (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+ Perform a call-back into the SEC simulator to get a memory value
+
+Arguments:
+ FfsHeader - General purpose data available to every PEIM
+ PeiServices - General purpose services available to every PEIM.
+
+Returns:
+ None
+
+**/
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
+ EMU_THUNK_PPI *Thunk;
+ UINT64 MemorySize;
+ EFI_PHYSICAL_ADDRESS MemoryBase;
+ UINTN Index;
+ EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;
+
+
+ DEBUG ((EFI_D_ERROR, "Emu Autoscan PEIM Loaded\n"));
+
+ //
+ // Get the PEI UNIX Autoscan PPI
+ //
+ Status = PeiServicesLocatePpi (
+ &gEmuThunkPpiGuid, // GUID
+ 0, // INSTANCE
+ &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR
+ (VOID **)&Thunk // PPI
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Index = 0;
+ do {
+ Status = Thunk->MemoryAutoScan (Index, &MemoryBase, &MemorySize);
+ if (!EFI_ERROR (Status)) {
+ Attributes =
+ (
+ 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
+ );
+
+ if (Index == 0) {
+ //
+ // Register the memory with the PEI Core
+ //
+ Status = PeiServicesInstallPeiMemory (MemoryBase, MemorySize);
+ ASSERT_EFI_ERROR (Status);
+
+ Attributes |= EFI_RESOURCE_ATTRIBUTE_TESTED;
+ }
+
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ Attributes,
+ MemoryBase,
+ MemorySize
+ );
+ }
+ Index++;
+ } while (!EFI_ERROR (Status));
+
+ //
+ // Build the CPU hob with 57-bit addressing and 16-bits of IO space.
+ //
+ BuildCpuHob (57, 16);
+
+ return Status;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/AutoScanPei/AutoScanPei.inf b/CdeEmuPkg/EmulatorPkg/AutoScanPei/AutoScanPei.inf
new file mode 100644
index 00000000000..dd49bb68f43
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/AutoScanPei/AutoScanPei.inf
@@ -0,0 +1,53 @@
+## @file
+# Component description file for EmuAutoScan module
+#
+# This module abstracts memory auto-scan in a Emu environment.
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = AutoScanPei
+ FILE_GUID = 2D6F6BCC-9681-8E42-8579-B57DCD0060F0
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = PeimInitializeAutoScanPei
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ AutoScanPei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+# MdeModulePkg/MdeModulePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+[LibraryClasses]
+ PeiServicesTablePointerLib
+ PeiServicesLib
+ HobLib
+ BaseMemoryLib
+ BaseLib
+ PeimEntryPoint
+ DebugLib
+
+
+[Ppis]
+ gEfiPeiMemoryDiscoveredPpiGuid # PPI ALWAYS_PRODUCED
+ gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED
+
+
+[Depex]
+ gEmuThunkPpiGuid AND gEfiPeiMasterBootModePpiGuid
+
diff --git a/CdeEmuPkg/EmulatorPkg/BootModePei/BootModePei.c b/CdeEmuPkg/EmulatorPkg/BootModePei/BootModePei.c
new file mode 100644
index 00000000000..17f18af2904
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/BootModePei/BootModePei.c
@@ -0,0 +1,88 @@
+/** @file
+
+Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+
+//
+// The package level header files this module uses
+//
+#include
+
+#include
+#include
+
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include
+#include
+//
+// The Library classes this module consumes
+//
+#include
+#include
+
+
+//
+// Module globals
+//
+EFI_PEI_PPI_DESCRIPTOR mPpiListBootMode = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMasterBootModePpiGuid,
+ NULL
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPpiListRecoveryBootMode = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiBootInRecoveryModePpiGuid,
+ NULL
+};
+
+EFI_STATUS
+EFIAPI
+InitializeBootMode (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Peform the boot mode determination logic
+
+Arguments:
+
+ PeiServices - General purpose services available to every PEIM.
+
+Returns:
+
+ Status - EFI_SUCCESS if the boot mode could be set
+
+**/
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+
+ DEBUG ((EFI_D_ERROR, "Emu Boot Mode PEIM Loaded\n"));
+
+ BootMode = FixedPcdGet32 (PcdEmuBootMode);
+
+ Status = PeiServicesSetBootMode (BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PeiServicesInstallPpi (&mPpiListBootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ if (BootMode == BOOT_IN_RECOVERY_MODE) {
+ Status = PeiServicesInstallPpi (&mPpiListRecoveryBootMode);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return Status;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/BootModePei/BootModePei.inf b/CdeEmuPkg/EmulatorPkg/BootModePei/BootModePei.inf
new file mode 100644
index 00000000000..c369dfe93a5
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/BootModePei/BootModePei.inf
@@ -0,0 +1,54 @@
+## @file
+# Component description file for BootMode module
+#
+# This module provides platform specific function to detect boot mode.
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BootModePei
+ FILE_GUID = 64196C76-58E3-0B4D-9484-B54F7C4349CA
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeBootMode
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ BootModePei.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+
+[LibraryClasses]
+ PeiServicesTablePointerLib
+ PeiServicesLib
+ BaseLib
+ PeimEntryPoint
+ DebugLib
+
+
+[Ppis]
+ gEfiPeiMasterBootModePpiGuid # PPI ALWAYS_PRODUCED
+ gEfiPeiBootInRecoveryModePpiGuid # PPI SOMETIMES_PRODUCED
+
+[FixedPcd]
+ gEmulatorPkgTokenSpaceGuid.PcdEmuBootMode
+
+[Depex]
+ TRUE
+
diff --git a/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/Cpu.c b/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/Cpu.c
new file mode 100644
index 00000000000..0a5b3c7d773
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/Cpu.c
@@ -0,0 +1,468 @@
+/*++ @file
+ Emu driver to produce CPU Architectural Protocol.
+
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011 - 2012, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CpuDriver.h"
+
+UINT64 mTimerPeriod;
+
+CPU_ARCH_PROTOCOL_PRIVATE mCpuTemplate = {
+ CPU_ARCH_PROT_PRIVATE_SIGNATURE,
+ NULL,
+ {
+ EmuFlushCpuDataCache,
+ EmuEnableInterrupt,
+ EmuDisableInterrupt,
+ EmuGetInterruptState,
+ EmuInit,
+ EmuRegisterInterruptHandler,
+ EmuGetTimerValue,
+ EmuSetMemoryAttributes,
+ 0,
+ 4
+ },
+ {
+ {
+ CpuMemoryServiceRead,
+ CpuMemoryServiceWrite
+ },
+ {
+ CpuIoServiceRead,
+ CpuIoServiceWrite
+ }
+ },
+ TRUE
+};
+
+#define EFI_CPU_DATA_MAXIMUM_LENGTH 0x100
+
+SMBIOS_TABLE_TYPE4 mCpuSmbiosType4 = {
+ { EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, sizeof (SMBIOS_TABLE_TYPE4), 0},
+ 1, // Socket String
+ ProcessorOther, // ProcessorType; ///< The enumeration value from PROCESSOR_TYPE_DATA.
+ ProcessorFamilyOther, // ProcessorFamily; ///< The enumeration value from PROCESSOR_FAMILY_DATA.
+ 2, // ProcessorManufacture String;
+ { // ProcessorId;
+ { // PROCESSOR_SIGNATURE
+ 0, // ProcessorSteppingId:4;
+ 0, // ProcessorModel: 4;
+ 0, // ProcessorFamily: 4;
+ 0, // ProcessorType: 2;
+ 0, // ProcessorReserved1: 2;
+ 0, // ProcessorXModel: 4;
+ 0, // ProcessorXFamily: 8;
+ 0, // ProcessorReserved2: 4;
+ },
+ { // PROCESSOR_FEATURE_FLAGS
+ 0, // ProcessorFpu :1;
+ 0, // ProcessorVme :1;
+ 0, // ProcessorDe :1;
+ 0, // ProcessorPse :1;
+ 0, // ProcessorTsc :1;
+ 0, // ProcessorMsr :1;
+ 0, // ProcessorPae :1;
+ 0, // ProcessorMce :1;
+ 0, // ProcessorCx8 :1;
+ 0, // ProcessorApic :1;
+ 0, // ProcessorReserved1 :1;
+ 0, // ProcessorSep :1;
+ 0, // ProcessorMtrr :1;
+ 0, // ProcessorPge :1;
+ 0, // ProcessorMca :1;
+ 0, // ProcessorCmov :1;
+ 0, // ProcessorPat :1;
+ 0, // ProcessorPse36 :1;
+ 0, // ProcessorPsn :1;
+ 0, // ProcessorClfsh :1;
+ 0, // ProcessorReserved2 :1;
+ 0, // ProcessorDs :1;
+ 0, // ProcessorAcpi :1;
+ 0, // ProcessorMmx :1;
+ 0, // ProcessorFxsr :1;
+ 0, // ProcessorSse :1;
+ 0, // ProcessorSse2 :1;
+ 0, // ProcessorSs :1;
+ 0, // ProcessorReserved3 :1;
+ 0, // ProcessorTm :1;
+ 0, // ProcessorReserved4 :2;
+ }
+ },
+ 3, // ProcessorVersion String;
+ { // Voltage;
+ 1, // ProcessorVoltageCapability5V :1;
+ 1, // ProcessorVoltageCapability3_3V :1;
+ 1, // ProcessorVoltageCapability2_9V :1;
+ 0, // ProcessorVoltageCapabilityReserved :1; ///< Bit 3, must be zero.
+ 0, // ProcessorVoltageReserved :3; ///< Bits 4-6, must be zero.
+ 0 // ProcessorVoltageIndicateLegacy :1;
+ },
+ 0, // ExternalClock;
+ 0, // MaxSpeed;
+ 0, // CurrentSpeed;
+ 0x41, // Status;
+ ProcessorUpgradeOther, // ProcessorUpgrade; ///< The enumeration value from PROCESSOR_UPGRADE.
+ 0, // L1CacheHandle;
+ 0, // L2CacheHandle;
+ 0, // L3CacheHandle;
+ 4, // SerialNumber;
+ 5, // AssetTag;
+ 6, // PartNumber;
+ 0, // CoreCount;
+ 0, // EnabledCoreCount;
+ 0, // ThreadCount;
+ 0, // ProcessorCharacteristics;
+ 0, // ProcessorFamily2;
+};
+
+CHAR8 *mCpuSmbiosType4Strings[] = {
+ "Socket",
+ "http://www.tianocore.org/edk2/",
+ "Emulated Processor",
+ "1.0",
+ "1.0",
+ "1.0",
+ NULL
+};
+
+
+/**
+ Create SMBIOS record.
+
+ Converts a fixed SMBIOS structure and an array of pointers to strings into
+ an SMBIOS record where the strings are cat'ed on the end of the fixed record
+ and terminated via a double NULL and add to SMBIOS table.
+
+ SMBIOS_TABLE_TYPE32 gSmbiosType12 = {
+ { EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS, sizeof (SMBIOS_TABLE_TYPE12), 0 },
+ 1 // StringCount
+ };
+ CHAR8 *gSmbiosType12Strings[] = {
+ "Not Found",
+ NULL
+ };
+
+ ...
+ LogSmbiosData (
+ (EFI_SMBIOS_TABLE_HEADER*)&gSmbiosType12,
+ gSmbiosType12Strings
+ );
+
+ @param Template Fixed SMBIOS structure, required.
+ @param StringArray Array of strings to convert to an SMBIOS string pack.
+ NULL is OK.
+
+**/
+EFI_STATUS
+LogSmbiosData (
+ IN EFI_SMBIOS_TABLE_HEADER *Template,
+ IN CHAR8 **StringPack
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBIOS_PROTOCOL *Smbios;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ EFI_SMBIOS_TABLE_HEADER *Record;
+ UINTN Index;
+ UINTN StringSize;
+ UINTN Size;
+ CHAR8 *Str;
+
+ //
+ // Locate Smbios protocol.
+ //
+ Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&Smbios);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Calculate the size of the fixed record and optional string pack
+ Size = Template->Length;
+ if (StringPack == NULL) {
+ // At least a double null is required
+ Size += 2;
+ } else {
+ for (Index = 0; StringPack[Index] != NULL; Index++) {
+ StringSize = AsciiStrSize (StringPack[Index]);
+ Size += StringSize;
+ }
+ if (StringPack[0] == NULL) {
+ // At least a double null is required
+ Size += 1;
+ }
+ // Don't forget the terminating double null
+ Size += 1;
+ }
+
+ // Copy over Template
+ Record = (EFI_SMBIOS_TABLE_HEADER *)AllocateZeroPool (Size);
+ if (Record == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (Record, Template, Template->Length);
+
+ // Append string pack
+ Str = ((CHAR8 *)Record) + Record->Length;
+ for (Index = 0; StringPack[Index] != NULL; Index++) {
+ StringSize = AsciiStrSize (StringPack[Index]);
+ CopyMem (Str, StringPack[Index], StringSize);
+ Str += StringSize;
+ }
+ *Str = 0;
+
+ SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
+ Status = Smbios->Add (
+ Smbios,
+ gImageHandle,
+ &SmbiosHandle,
+ Record
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ FreePool (Record);
+ return Status;
+}
+
+
+
+
+VOID
+CpuUpdateSmbios (
+ IN UINTN MaxCpus
+ )
+{
+ mCpuSmbiosType4.CoreCount = (UINT8) MaxCpus;
+ mCpuSmbiosType4.EnabledCoreCount = (UINT8) MaxCpus;
+ mCpuSmbiosType4.ThreadCount = (UINT8) MaxCpus;
+ //
+ // The value of 1234 is fake value for CPU frequency
+ //
+ mCpuSmbiosType4.CurrentSpeed = 1234;
+ LogSmbiosData ((EFI_SMBIOS_TABLE_HEADER *)&mCpuSmbiosType4, mCpuSmbiosType4Strings);
+}
+
+
+//
+// Service routines for the driver
+//
+EFI_STATUS
+EFIAPI
+EmuFlushCpuDataCache (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length,
+ IN EFI_CPU_FLUSH_TYPE FlushType
+ )
+{
+ if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {
+ //
+ // Only WB flush is supported. We actually need do nothing on Emu emulator
+ // environment. Classify this to follow EFI spec
+ //
+ return EFI_SUCCESS;
+ }
+ //
+ // Other flush types are not supported by Emu emulator
+ //
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+EmuEnableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ )
+{
+ CPU_ARCH_PROTOCOL_PRIVATE *Private;
+
+ Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
+ Private->InterruptState = TRUE;
+ gEmuThunk->EnableInterrupt ();
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EmuDisableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ )
+{
+ CPU_ARCH_PROTOCOL_PRIVATE *Private;
+
+ Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
+ Private->InterruptState = FALSE;
+ gEmuThunk->DisableInterrupt ();
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EmuGetInterruptState (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ OUT BOOLEAN *State
+ )
+{
+ CPU_ARCH_PROTOCOL_PRIVATE *Private;
+
+ if (State == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS (This);
+ *State = Private->InterruptState;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EmuInit (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_CPU_INIT_TYPE InitType
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+EmuRegisterInterruptHandler (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ )
+{
+ //
+ // Do parameter checking for EFI spec conformance
+ //
+ if (InterruptType < 0 || InterruptType > 0xff) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Do nothing for Emu emulation
+ //
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+EmuGetTimerValue (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN UINT32 TimerIndex,
+ OUT UINT64 *TimerValue,
+ OUT UINT64 *TimerPeriod OPTIONAL
+ )
+{
+ if (TimerValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (TimerIndex != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *TimerValue = gEmuThunk->QueryPerformanceCounter ();
+
+ if (TimerPeriod != NULL) {
+ *TimerPeriod = mTimerPeriod;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+EmuSetMemoryAttributes (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ )
+{
+ //
+ // Check for invalid parameter for Spec conformance
+ //
+ if (Length == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Do nothing for Nt32 emulation
+ //
+ return EFI_UNSUPPORTED;
+}
+
+
+
+
+/**
+ Callback function for idle events.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+IdleLoopEventCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ gEmuThunk->CpuSleep ();
+}
+
+
+EFI_STATUS
+EFIAPI
+InitializeCpu (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT64 Frequency;
+ EFI_EVENT IdleLoopEvent;
+ UINTN MaxCpu;
+
+ //
+ // Retrieve the frequency of the performance counter in Hz.
+ //
+ Frequency = gEmuThunk->QueryPerformanceFrequency ();
+
+ //
+ // Convert frequency in Hz to a clock period in femtoseconds.
+ //
+ mTimerPeriod = DivU64x64Remainder (1000000000000000ULL, Frequency, NULL);
+
+ CpuMpServicesInit (&MaxCpu);
+
+ CpuUpdateSmbios (MaxCpu);
+
+
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ IdleLoopEventCallback,
+ NULL,
+ &gIdleLoopEventGuid,
+ &IdleLoopEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mCpuTemplate.Handle,
+ &gEfiCpuArchProtocolGuid, &mCpuTemplate.Cpu,
+ &gEfiCpuIo2ProtocolGuid, &mCpuTemplate.CpuIo,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/Cpu.inf b/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/Cpu.inf
new file mode 100644
index 00000000000..ceb751f0016
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/Cpu.inf
@@ -0,0 +1,67 @@
+## @file
+# Component description file for Cpu module.
+#
+# This CPU module abstracts the interrupt subsystem of a platform and the CPU-specific setjump-long pair.
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Cpu
+ FILE_GUID = f3794b60-8985-11db-8e53-0040d02b1835
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeCpu
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ CpuIo.c
+ Cpu.c
+ CpuDriver.h
+ MpService.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ UefiDriverEntryPoint
+ UefiLib
+ HiiLib
+ DebugLib
+ BaseLib
+ EmuThunkLib
+ PcdLib
+
+[Protocols]
+ gEmuIoThunkProtocolGuid # PROTOCOL_NOTIFY SOMETIMES_CONSUMED
+ gEfiSmbiosProtocolGuid # PROTOCOL SOMETIMES_CONSUMED
+ gEfiCpuIo2ProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gEfiCpuArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gEmuThreadThunkProtocolGuid
+ gEfiMpServiceProtocolGuid
+
+[Guids]
+ gIdleLoopEventGuid ## CONSUMES ## GUID
+
+[Pcd]
+ gEmulatorPkgTokenSpaceGuid.PcdEmuMpServicesPollingInterval
+
+[Depex]
+ gEfiSmbiosProtocolGuid
diff --git a/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/CpuDriver.h b/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/CpuDriver.h
new file mode 100644
index 00000000000..3910691e66b
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/CpuDriver.h
@@ -0,0 +1,236 @@
+/*++ @file
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _CPU_ARCHITECTURAL_PROTOCOL_DRIVER_H_
+#define _CPU_ARCHITECTURAL_PROTOCOL_DRIVER_H_
+
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+
+//
+// Internal Data Structures
+//
+#define CPU_ARCH_PROT_PRIVATE_SIGNATURE SIGNATURE_32 ('c', 'a', 'p', 'd')
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+
+ EFI_CPU_ARCH_PROTOCOL Cpu;
+ EFI_CPU_IO2_PROTOCOL CpuIo;
+
+ //
+ // Local Data for CPU interface goes here
+ //
+ BOOLEAN InterruptState;
+
+} CPU_ARCH_PROTOCOL_PRIVATE;
+
+#define CPU_ARCH_PROTOCOL_PRIVATE_DATA_FROM_THIS(a) \
+ CR (a, \
+ CPU_ARCH_PROTOCOL_PRIVATE, \
+ Cpu, \
+ CPU_ARCH_PROT_PRIVATE_SIGNATURE \
+ )
+
+
+
+typedef enum {
+ CPU_STATE_IDLE,
+ CPU_STATE_BLOCKED,
+ CPU_STATE_READY,
+ CPU_STATE_BUSY,
+ CPU_STATE_FINISHED
+} PROCESSOR_STATE;
+
+
+//
+// Define Individual Processor Data block.
+//
+typedef struct {
+ EFI_PROCESSOR_INFORMATION Info;
+ EFI_AP_PROCEDURE Procedure;
+ VOID *Parameter;
+ VOID *StateLock;
+ VOID *ProcedureLock;
+ PROCESSOR_STATE State;
+ EFI_EVENT CheckThisAPEvent;
+} PROCESSOR_DATA_BLOCK;
+
+
+//
+// Define MP data block which consumes individual processor block.
+//
+typedef struct {
+ UINTN NumberOfProcessors;
+ UINTN NumberOfEnabledProcessors;
+ EFI_EVENT CheckAllAPsEvent;
+ EFI_EVENT WaitEvent;
+ UINTN FinishCount;
+ UINTN StartCount;
+ EFI_AP_PROCEDURE Procedure;
+ VOID *ProcedureArgument;
+ BOOLEAN SingleThread;
+ UINTN StartedNumber;
+ PROCESSOR_DATA_BLOCK *ProcessorData;
+ UINTN Timeout;
+ UINTN *FailedList;
+ UINTN FailedListIndex;
+ BOOLEAN TimeoutActive;
+} MP_SYSTEM_DATA;
+
+
+
+
+
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN OUT VOID *UserBuffer
+ );
+
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN OUT VOID *UserBuffer
+ );
+
+EFI_STATUS
+EFIAPI
+InitializeCpu (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+EFI_STATUS
+EFIAPI
+EmuFlushCpuDataCache (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length,
+ IN EFI_CPU_FLUSH_TYPE FlushType
+ );
+
+EFI_STATUS
+EFIAPI
+EmuEnableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ );
+
+EFI_STATUS
+EFIAPI
+EmuDisableInterrupt (
+ IN EFI_CPU_ARCH_PROTOCOL *This
+ );
+
+EFI_STATUS
+EFIAPI
+EmuGetInterruptState (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ OUT BOOLEAN *State
+ );
+
+EFI_STATUS
+EFIAPI
+EmuInit (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_CPU_INIT_TYPE InitType
+ );
+
+EFI_STATUS
+EFIAPI
+EmuRegisterInterruptHandler (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ );
+
+EFI_STATUS
+EFIAPI
+EmuGetTimerValue (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN UINT32 TimerIndex,
+ OUT UINT64 *TimerValue,
+ OUT UINT64 *TimerPeriod OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+EmuSetMemoryAttributes (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ );
+
+EFI_STATUS
+CpuMpServicesInit (
+ OUT UINTN *MaxCores
+ );
+
+EFI_STATUS
+EFIAPI
+CpuMpServicesWhoAmI (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ OUT UINTN *ProcessorNumber
+ );
+
+extern EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate;
+
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/CpuIo.c b/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/CpuIo.c
new file mode 100644
index 00000000000..9a1c8be650d
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/CpuIo.c
@@ -0,0 +1,324 @@
+/*++ @file
+ This is the code that publishes the CPU I/O Protocol.
+ The intent herein is to have a single I/O service that can load
+ as early as possible, extend into runtime, and be layered upon by
+ the implementations of architectural protocols and the PCI Root
+ Bridge I/O Protocol.
+
+
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define IA32_MAX_IO_ADDRESS 0xFFFF
+#define IA32_MAX_MEM_ADDRESS 0xFFFFFFFF
+
+EFI_STATUS
+CpuIoCheckAddressRange (
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer,
+ IN UINT64 Limit
+ );
+
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceRead (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Perform the Memory Access Read service for the CPU I/O Protocol
+
+Arguments:
+
+ Pointer to an instance of the CPU I/O Protocol
+ Width of the Memory Access
+ Address of the Memory access
+ Count of the number of accesses to perform
+ Pointer to the buffer to read or write from memory
+
+Returns:
+
+ Status
+
+ EFI_SUCCESS - The data was read from or written to the EFI
+ System.
+ EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
+ EFI_INVALID_PARAMETER - Buffer is NULL.
+ EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
+ EFI_UNSUPPORTED - The address range specified by Address, Width,
+ and Count is not valid for this EFI System.
+
+**/
+{
+ EFI_STATUS Status;
+
+ if (!Buffer) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Do nothing for Nt32 version
+ //
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+CpuMemoryServiceWrite (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Perform the Memory Access Read service for the CPU I/O Protocol
+
+Arguments:
+
+ Pointer to an instance of the CPU I/O Protocol
+ Width of the Memory Access
+ Address of the Memory access
+ Count of the number of accesses to perform
+ Pointer to the buffer to read or write from memory
+
+Returns:
+
+ Status
+
+ EFI_SUCCESS - The data was read from or written to the EFI System.
+ EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
+ EFI_INVALID_PARAMETER - Buffer is NULL.
+ EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
+ EFI_UNSUPPORTED - The address range specified by Address, Width, and
+ Count is not valid for this EFI System.
+
+**/
+{
+ EFI_STATUS Status;
+
+ if (!Buffer) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = CpuIoCheckAddressRange (Width, Address, Count, Buffer, IA32_MAX_MEM_ADDRESS);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Do nothing for Nt32 version
+ //
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+CpuIoServiceRead (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN OUT VOID *UserBuffer
+ )
+/*++
+
+Routine Description:
+
+ This is the service that implements the I/O read
+
+Arguments:
+
+ Pointer to an instance of the CPU I/O Protocol
+ Width of the Memory Access
+ Address of the I/O access
+ Count of the number of accesses to perform
+ Pointer to the buffer to read or write from I/O space
+
+Returns:
+
+ Status
+ EFI_SUCCESS - The data was read from or written to the EFI System.
+ EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
+ EFI_INVALID_PARAMETER - Buffer is NULL.
+ EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
+ EFI_UNSUPPORTED - The address range specified by Address, Width, and
+ Count is not valid for this EFI System.
+**/
+{
+ UINTN Address;
+ EFI_STATUS Status;
+
+ if (!UserBuffer) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Address = (UINTN) UserAddress;
+
+ if (Width >= EfiCpuIoWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Do nothing for Nt32 version
+ //
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+CpuIoServiceWrite (
+ IN EFI_CPU_IO2_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN OUT VOID *UserBuffer
+ )
+/*++
+
+Routine Description:
+
+
+ This is the service that implements the I/O Write
+
+Arguments:
+
+ Pointer to an instance of the CPU I/O Protocol
+ Width of the Memory Access
+ Address of the I/O access
+ Count of the number of accesses to perform
+ Pointer to the buffer to read or write from I/O space
+
+Returns:
+
+ Status
+
+ Status
+ EFI_SUCCESS - The data was read from or written to the EFI System.
+ EFI_INVALID_PARAMETER - Width is invalid for this EFI System.
+ EFI_INVALID_PARAMETER - Buffer is NULL.
+ EFI_UNSUPPORTED - The Buffer is not aligned for the given Width.
+ EFI_UNSUPPORTED - The address range specified by Address, Width, and
+ Count is not valid for this EFI System.
+
+**/
+{
+ UINTN Address;
+ EFI_STATUS Status;
+
+ if (!UserBuffer) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Address = (UINTN) UserAddress;
+
+ if (Width >= EfiCpuIoWidthMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = CpuIoCheckAddressRange (Width, Address, Count, UserBuffer, IA32_MAX_IO_ADDRESS);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Do nothing for Nt32 version
+ //
+ return EFI_SUCCESS;
+}
+
+
+/*++
+
+Routine Description:
+
+Arguments:
+
+ Width - TODO: add argument description
+ Address - TODO: add argument description
+ Count - TODO: add argument description
+ Buffer - TODO: add argument description
+ Limit - TODO: add argument description
+
+Returns:
+
+ EFI_UNSUPPORTED - TODO: Add description for return value
+ EFI_UNSUPPORTED - TODO: Add description for return value
+ EFI_UNSUPPORTED - TODO: Add description for return value
+ EFI_SUCCESS - TODO: Add description for return value
+
+**/
+EFI_STATUS
+CpuIoCheckAddressRange (
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN VOID *Buffer,
+ IN UINT64 Limit
+ )
+{
+ UINTN AlignMask;
+
+ if (Address > Limit) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // For FiFo type, the target address won't increase during the access, so treat count as 1
+ //
+ if (Width >= EfiCpuIoWidthFifoUint8 && Width <= EfiCpuIoWidthFifoUint64) {
+ Count = 1;
+ }
+
+ Width = Width & 0x03;
+ if ((Address - 1 + LShiftU64 (Count, Width)) > Limit) {
+ return EFI_UNSUPPORTED;
+ }
+
+ AlignMask = (1 << Width) - 1;
+ if ((UINTN) Buffer & AlignMask) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
diff --git a/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/MpService.c b/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/MpService.c
new file mode 100644
index 00000000000..fd4ff30dca0
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/CpuRuntimeDxe/MpService.c
@@ -0,0 +1,1404 @@
+/** @file
+ Construct MP Services Protocol on top of the EMU Thread protocol.
+ This code makes APs show up in the emulator. PcdEmuApCount is the
+ number of APs the emulator should produce.
+
+ The MP Services Protocol provides a generalized way of performing following tasks:
+ - Retrieving information of multi-processor environment and MP-related status of
+ specific processors.
+ - Dispatching user-provided function to APs.
+ - Maintain MP-related processor status.
+
+ The MP Services Protocol must be produced on any system with more than one logical
+ processor.
+
+ The Protocol is available only during boot time.
+
+ MP Services Protocol is hardware-independent. Most of the logic of this protocol
+ is architecturally neutral. It abstracts the multi-processor environment and
+ status of processors, and provides interfaces to retrieve information, maintain,
+ and dispatch.
+
+ MP Services Protocol may be consumed by ACPI module. The ACPI module may use this
+ protocol to retrieve data that are needed for an MP platform and report them to OS.
+ MP Services Protocol may also be used to program and configure processors, such
+ as MTRR synchronization for memory space attributes setting in DXE Services.
+ MP Services Protocol may be used by non-CPU DXE drivers to speed up platform boot
+ by taking advantage of the processing capabilities of the APs, for example, using
+ APs to help test system memory in parallel with other device initialization.
+ Diagnostics applications may also use this protocol for multi-processor.
+
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+Portitions Copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "CpuDriver.h"
+
+
+MP_SYSTEM_DATA gMPSystem;
+EMU_THREAD_THUNK_PROTOCOL *gThread = NULL;
+EFI_EVENT gReadToBootEvent;
+BOOLEAN gReadToBoot = FALSE;
+UINTN gPollInterval;
+
+
+BOOLEAN
+IsBSP (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN ProcessorNumber;
+
+ Status = CpuMpServicesWhoAmI (&mMpServicesTemplate, &ProcessorNumber);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ return (gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) != 0;
+}
+
+
+VOID
+SetApProcedure (
+ IN PROCESSOR_DATA_BLOCK *Processor,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN VOID *ProcedureArgument
+ )
+{
+ gThread->MutexLock (Processor->ProcedureLock);
+ Processor->Parameter = ProcedureArgument;
+ Processor->Procedure = Procedure;
+ gThread->MutexUnlock (Processor->ProcedureLock);
+}
+
+
+EFI_STATUS
+GetNextBlockedNumber (
+ OUT UINTN *NextNumber
+ )
+{
+ UINTN Number;
+ PROCESSOR_STATE ProcessorState;
+ PROCESSOR_DATA_BLOCK *Data;
+
+ for (Number = 0; Number < gMPSystem.NumberOfProcessors; Number++) {
+ Data = &gMPSystem.ProcessorData[Number];
+ if ((Data->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) != 0) {
+ // Skip BSP
+ continue;
+ }
+
+ gThread->MutexLock (Data->StateLock);
+ ProcessorState = Data->State;
+ gThread->MutexUnlock (Data->StateLock);
+
+ if (ProcessorState == CPU_STATE_BLOCKED) {
+ *NextNumber = Number;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ * Calculated and stalled the interval time by BSP to check whether
+ * the APs have finished.
+ *
+ * @param[in] Timeout The time limit in microseconds for
+ * APs to return from Procedure.
+ *
+ * @retval StallTime Time of execution stall.
+**/
+UINTN
+CalculateAndStallInterval (
+ IN UINTN Timeout
+ )
+{
+ UINTN StallTime;
+
+ if (Timeout < gPollInterval && Timeout != 0) {
+ StallTime = Timeout;
+ } else {
+ StallTime = gPollInterval;
+ }
+ gBS->Stall (StallTime);
+
+ return StallTime;
+}
+
+/**
+ This service retrieves the number of logical processor in the platform
+ and the number of those logical processors that are enabled on this boot.
+ This service may only be called from the BSP.
+
+ This function is used to retrieve the following information:
+ - The number of logical processors that are present in the system.
+ - The number of enabled logical processors in the system at the instant
+ this call is made.
+
+ Because MP Service Protocol provides services to enable and disable processors
+ dynamically, the number of enabled logical processors may vary during the
+ course of a boot session.
+
+ If this service is called from an AP, then EFI_DEVICE_ERROR is returned.
+ If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then
+ EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors
+ is returned in NumberOfProcessors, the number of currently enabled processor
+ is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[out] NumberOfProcessors Pointer to the total number of logical
+ processors in the system, including the BSP
+ and disabled APs.
+ @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical
+ processors that exist in system, including
+ the BSP.
+
+ @retval EFI_SUCCESS The number of logical processors and enabled
+ logical processors was retrieved.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL.
+ @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMpServicesGetNumberOfProcessors (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ OUT UINTN *NumberOfProcessors,
+ OUT UINTN *NumberOfEnabledProcessors
+ )
+{
+ if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IsBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ *NumberOfProcessors = gMPSystem.NumberOfProcessors;
+ *NumberOfEnabledProcessors = gMPSystem.NumberOfEnabledProcessors;
+ return EFI_SUCCESS;
+}
+
+
+
+/**
+ Gets detailed MP-related information on the requested processor at the
+ instant this call is made. This service may only be called from the BSP.
+
+ This service retrieves detailed MP-related information about any processor
+ on the platform. Note the following:
+ - The processor information may change during the course of a boot session.
+ - The information presented here is entirely MP related.
+
+ Information regarding the number of caches and their sizes, frequency of operation,
+ slot numbers is all considered platform-related information and is not provided
+ by this service.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] ProcessorNumber The handle number of processor.
+ @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
+ the requested processor is deposited.
+
+ @retval EFI_SUCCESS Processor information was returned.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist in the platform.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMpServicesGetProcessorInfo (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
+ )
+{
+ if (ProcessorInfoBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IsBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ProcessorNumber >= gMPSystem.NumberOfProcessors) {
+ return EFI_NOT_FOUND;
+ }
+
+ CopyMem (ProcessorInfoBuffer, &gMPSystem.ProcessorData[ProcessorNumber], sizeof (EFI_PROCESSOR_INFORMATION));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This service executes a caller provided function on all enabled APs. APs can
+ run either simultaneously or one at a time in sequence. This service supports
+ both blocking and non-blocking requests. The non-blocking requests use EFI
+ events so the BSP can detect when the APs have finished. This service may only
+ be called from the BSP.
+
+ This function is used to dispatch all the enabled APs to the function specified
+ by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned
+ immediately and Procedure is not started on any AP.
+
+ If SingleThread is TRUE, all the enabled APs execute the function specified by
+ Procedure one by one, in ascending order of processor handle number. Otherwise,
+ all the enabled APs execute the function specified by Procedure simultaneously.
+
+ If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all
+ APs finish or TimeoutInMicroseconds expires. Otherwise, execution is in non-blocking
+ mode, and the BSP returns from this service without waiting for APs. If a
+ non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
+ is signaled, then EFI_UNSUPPORTED must be returned.
+
+ If the timeout specified by TimeoutInMicroseconds expires before all APs return
+ from Procedure, then Procedure on the failed APs is terminated. All enabled APs
+ are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its
+ content points to the list of processor handle numbers in which Procedure was
+ terminated.
+
+ Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ to make sure that the nature of the code that is executed on the BSP and the
+ dispatched APs is well controlled. The MP Services Protocol does not guarantee
+ that the Procedure function is MP-safe. Hence, the tasks that can be run in
+ parallel are limited to certain independent tasks and well-controlled exclusive
+ code. EFI services and protocols may not be called by APs unless otherwise
+ specified.
+
+ In blocking execution mode, BSP waits until all APs finish or
+ TimeoutInMicroseconds expires.
+
+ In non-blocking execution mode, BSP is freed to return to the caller and then
+ proceed to the next task without having to wait for APs. The following
+ sequence needs to occur in a non-blocking execution mode:
+
+ -# The caller that intends to use this MP Services Protocol in non-blocking
+ mode creates WaitEvent by calling the EFI CreateEvent() service. The caller
+ invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent
+ is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests
+ the function specified by Procedure to be started on all the enabled APs,
+ and releases the BSP to continue with other tasks.
+ -# The caller can use the CheckEvent() and WaitForEvent() services to check
+ the state of the WaitEvent created in step 1.
+ -# When the APs complete their task or TimeoutInMicroSecondss expires, the MP
+ Service signals WaitEvent by calling the EFI SignalEvent() function. If
+ FailedCpuList is not NULL, its content is available when WaitEvent is
+ signaled. If all APs returned from Procedure prior to the timeout, then
+ FailedCpuList is set to NULL. If not all APs return from Procedure before
+ the timeout, then FailedCpuList is filled in with the list of the failed
+ APs. The buffer is allocated by MP Service Protocol using AllocatePool().
+ It is the caller's responsibility to free the buffer with FreePool() service.
+ -# This invocation of SignalEvent() function informs the caller that invoked
+ EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed
+ the specified task or a timeout occurred. The contents of FailedCpuList
+ can be examined to determine which APs did not complete the specified task
+ prior to the timeout.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] SingleThread If TRUE, then all the enabled APs execute
+ the function specified by Procedure one by
+ one, in ascending order of processor handle
+ number. If FALSE, then all the enabled APs
+ execute the function specified by Procedure
+ simultaneously.
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
+ all return from Procedure, or TimeoutInMicroseconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode. Zero means
+ infinity. If the timeout expires before
+ all APs return from Procedure, then Procedure
+ on the failed APs is terminated. All enabled
+ APs are available for next function assigned
+ by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise,
+ if all APs finish successfully, then its
+ content is set to NULL. If not all APs
+ finish before timeout expires, then its
+ content is set to address of the buffer
+ holding handle numbers of the failed APs.
+ The buffer is allocated by MP Service Protocol,
+ and it's the caller's responsibility to
+ free the buffer with FreePool() service.
+ In blocking mode, it is ready for consumption
+ when the call returns. In non-blocking mode,
+ it is ready when WaitEvent is signaled. The
+ list of failed CPU is terminated by
+ END_OF_CPU_LIST.
+
+ @retval EFI_SUCCESS In blocking mode, all APs have finished before
+ the timeout expired.
+ @retval EFI_SUCCESS In non-blocking mode, function has been dispatched
+ to all enabled APs.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_DEVICE_ERROR Caller processor is AP.
+ @retval EFI_NOT_STARTED No enabled APs exist in the system.
+ @retval EFI_NOT_READY Any enabled APs are busy.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ all enabled APs have finished.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMpServicesStartupAllAps (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN BOOLEAN SingleThread,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT UINTN **FailedCpuList OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ PROCESSOR_DATA_BLOCK *ProcessorData;
+ UINTN Number;
+ UINTN NextNumber;
+ PROCESSOR_STATE APInitialState;
+ PROCESSOR_STATE ProcessorState;
+ UINTN Timeout;
+
+
+ if (!IsBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (gMPSystem.NumberOfProcessors == 1) {
+ return EFI_NOT_STARTED;
+ }
+
+ if (Procedure == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((WaitEvent != NULL) && gReadToBoot) {
+ return EFI_UNSUPPORTED;
+ }
+
+ for (Number = 0; Number < gMPSystem.NumberOfProcessors; Number++) {
+ ProcessorData = &gMPSystem.ProcessorData[Number];
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
+ // Skip BSP
+ continue;
+ }
+
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
+ // Skip Disabled processors
+ continue;
+ }
+ gThread->MutexLock(ProcessorData->StateLock);
+ if (ProcessorData->State != CPU_STATE_IDLE) {
+ gThread->MutexUnlock (ProcessorData->StateLock);
+ return EFI_NOT_READY;
+ }
+ gThread->MutexUnlock(ProcessorData->StateLock);
+ }
+
+ if (FailedCpuList != NULL) {
+ gMPSystem.FailedList = AllocatePool ((gMPSystem.NumberOfProcessors + 1) * sizeof (UINTN));
+ if (gMPSystem.FailedList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ SetMemN (gMPSystem.FailedList, (gMPSystem.NumberOfProcessors + 1) * sizeof (UINTN), END_OF_CPU_LIST);
+ gMPSystem.FailedListIndex = 0;
+ *FailedCpuList = gMPSystem.FailedList;
+ }
+
+ Timeout = TimeoutInMicroseconds;
+
+ ProcessorData = NULL;
+
+ gMPSystem.FinishCount = 0;
+ gMPSystem.StartCount = 0;
+ gMPSystem.SingleThread = SingleThread;
+ APInitialState = CPU_STATE_READY;
+
+ for (Number = 0; Number < gMPSystem.NumberOfProcessors; Number++) {
+ ProcessorData = &gMPSystem.ProcessorData[Number];
+
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
+ // Skip BSP
+ continue;
+ }
+
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
+ // Skip Disabled processors
+ gMPSystem.FailedList[gMPSystem.FailedListIndex++] = Number;
+ continue;
+ }
+
+ //
+ // Get APs prepared, and put failing APs into FailedCpuList
+ // if "SingleThread", only 1 AP will put to ready state, other AP will be put to ready
+ // state 1 by 1, until the previous 1 finished its task
+ // if not "SingleThread", all APs are put to ready state from the beginning
+ //
+ gThread->MutexLock(ProcessorData->StateLock);
+ ASSERT (ProcessorData->State == CPU_STATE_IDLE);
+ ProcessorData->State = APInitialState;
+ gThread->MutexUnlock (ProcessorData->StateLock);
+
+ gMPSystem.StartCount++;
+ if (SingleThread) {
+ APInitialState = CPU_STATE_BLOCKED;
+ }
+ }
+
+ if (WaitEvent != NULL) {
+ for (Number = 0; Number < gMPSystem.NumberOfProcessors; Number++) {
+ ProcessorData = &gMPSystem.ProcessorData[Number];
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
+ // Skip BSP
+ continue;
+ }
+
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
+ // Skip Disabled processors
+ continue;
+ }
+
+ gThread->MutexLock (ProcessorData->StateLock);
+ ProcessorState = ProcessorData->State;
+ gThread->MutexUnlock (ProcessorData->StateLock);
+
+ if (ProcessorState == CPU_STATE_READY) {
+ SetApProcedure (ProcessorData, Procedure, ProcedureArgument);
+ }
+ }
+
+ //
+ // Save data into private data structure, and create timer to poll AP state before exiting
+ //
+ gMPSystem.Procedure = Procedure;
+ gMPSystem.ProcedureArgument = ProcedureArgument;
+ gMPSystem.WaitEvent = WaitEvent;
+ gMPSystem.Timeout = TimeoutInMicroseconds;
+ gMPSystem.TimeoutActive = (BOOLEAN)(TimeoutInMicroseconds != 0);
+ Status = gBS->SetTimer (
+ gMPSystem.CheckAllAPsEvent,
+ TimerPeriodic,
+ gPollInterval
+ );
+ return Status;
+
+ }
+
+ while (TRUE) {
+ for (Number = 0; Number < gMPSystem.NumberOfProcessors; Number++) {
+ ProcessorData = &gMPSystem.ProcessorData[Number];
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
+ // Skip BSP
+ continue;
+ }
+
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
+ // Skip Disabled processors
+ continue;
+ }
+
+ gThread->MutexLock (ProcessorData->StateLock);
+ ProcessorState = ProcessorData->State;
+ gThread->MutexUnlock (ProcessorData->StateLock);
+
+ switch (ProcessorState) {
+ case CPU_STATE_READY:
+ SetApProcedure (ProcessorData, Procedure, ProcedureArgument);
+ break;
+
+ case CPU_STATE_FINISHED:
+ gMPSystem.FinishCount++;
+ if (SingleThread) {
+ Status = GetNextBlockedNumber (&NextNumber);
+ if (!EFI_ERROR (Status)) {
+ gThread->MutexLock (gMPSystem.ProcessorData[NextNumber].StateLock);
+ gMPSystem.ProcessorData[NextNumber].State = CPU_STATE_READY;
+ gThread->MutexUnlock (gMPSystem.ProcessorData[NextNumber].StateLock);
+ }
+ }
+
+ gThread->MutexLock (ProcessorData->StateLock);
+ ProcessorData->State = CPU_STATE_IDLE;
+ gThread->MutexUnlock (ProcessorData->StateLock);
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (gMPSystem.FinishCount == gMPSystem.StartCount) {
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
+
+ if ((TimeoutInMicroseconds != 0) && (Timeout == 0)) {
+ Status = EFI_TIMEOUT;
+ goto Done;
+ }
+
+ Timeout -= CalculateAndStallInterval (Timeout);
+ }
+
+Done:
+ if (FailedCpuList != NULL) {
+ if (gMPSystem.FailedListIndex == 0) {
+ FreePool (*FailedCpuList);
+ *FailedCpuList = NULL;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This service lets the caller get one enabled AP to execute a caller-provided
+ function. The caller can request the BSP to either wait for the completion
+ of the AP or just proceed with the next task by using the EFI event mechanism.
+ See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking
+ execution support. This service may only be called from the BSP.
+
+ This function is used to dispatch one enabled AP to the function specified by
+ Procedure passing in the argument specified by ProcedureArgument. If WaitEvent
+ is NULL, execution is in blocking mode. The BSP waits until the AP finishes or
+ TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode.
+ BSP proceeds to the next task without waiting for the AP. If a non-blocking mode
+ is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled,
+ then EFI_UNSUPPORTED must be returned.
+
+ If the timeout specified by TimeoutInMicroseconds expires before the AP returns
+ from Procedure, then execution of Procedure by the AP is terminated. The AP is
+ available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and
+ EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL
+ instance.
+ @param[in] Procedure A pointer to the function to be run on
+ enabled APs of the system. See type
+ EFI_AP_PROCEDURE.
+ @param[in] ProcessorNumber The handle number of the AP. The range is
+ from 0 to the total number of logical
+ processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] WaitEvent The event created by the caller with CreateEvent()
+ service. If it is NULL, then execute in
+ blocking mode. BSP waits until all APs finish
+ or TimeoutInMicroseconds expires. If it's
+ not NULL, then execute in non-blocking mode.
+ BSP requests the function specified by
+ Procedure to be started on all the enabled
+ APs, and go on executing immediately. If
+ all return from Procedure or TimeoutInMicroseconds
+ expires, this event is signaled. The BSP
+ can use the CheckEvent() or WaitForEvent()
+ services to check the state of event. Type
+ EFI_EVENT is defined in CreateEvent() in
+ the Unified Extensible Firmware Interface
+ Specification.
+ @param[in] TimeoutInMicrosecsond Indicates the time limit in microseconds for
+ APs to return from Procedure, either for
+ blocking or non-blocking mode. Zero means
+ infinity. If the timeout expires before
+ all APs return from Procedure, then Procedure
+ on the failed APs is terminated. All enabled
+ APs are available for next function assigned
+ by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs()
+ or EFI_MP_SERVICES_PROTOCOL.StartupThisAP().
+ If the timeout expires in blocking mode,
+ BSP returns EFI_TIMEOUT. If the timeout
+ expires in non-blocking mode, WaitEvent
+ is signaled with SignalEvent().
+ @param[in] ProcedureArgument The parameter passed into Procedure for
+ all APs.
+ @param[out] Finished If NULL, this parameter is ignored. In
+ blocking mode, this parameter is ignored.
+ In non-blocking mode, if AP returns from
+ Procedure before the timeout expires, its
+ content is set to TRUE. Otherwise, the
+ value is set to FALSE. The caller can
+ determine if the AP returned from Procedure
+ by evaluating this value.
+
+ @retval EFI_SUCCESS In blocking mode, specified AP finished before
+ the timeout expires.
+ @retval EFI_SUCCESS In non-blocking mode, the function has been
+ dispatched to specified AP.
+ @retval EFI_UNSUPPORTED A non-blocking mode request was made after the
+ UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was
+ signaled.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_TIMEOUT In blocking mode, the timeout expired before
+ the specified AP has finished.
+ @retval EFI_NOT_READY The specified AP is busy.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP.
+ @retval EFI_INVALID_PARAMETER Procedure is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMpServicesStartupThisAP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN ProcessorNumber,
+ IN EFI_EVENT WaitEvent OPTIONAL,
+ IN UINTN TimeoutInMicroseconds,
+ IN VOID *ProcedureArgument OPTIONAL,
+ OUT BOOLEAN *Finished OPTIONAL
+ )
+{
+ UINTN Timeout;
+
+ if (!IsBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (Procedure == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ProcessorNumber >= gMPSystem.NumberOfProcessors) {
+ return EFI_NOT_FOUND;
+ }
+
+ if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ gThread->MutexLock(gMPSystem.ProcessorData[ProcessorNumber].StateLock);
+ if (gMPSystem.ProcessorData[ProcessorNumber].State != CPU_STATE_IDLE) {
+ gThread->MutexUnlock(gMPSystem.ProcessorData[ProcessorNumber].StateLock);
+ return EFI_NOT_READY;
+ }
+ gThread->MutexUnlock(gMPSystem.ProcessorData[ProcessorNumber].StateLock);
+
+ if ((WaitEvent != NULL) && gReadToBoot) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Timeout = TimeoutInMicroseconds;
+
+ gMPSystem.StartCount = 1;
+ gMPSystem.FinishCount = 0;
+
+ SetApProcedure (&gMPSystem.ProcessorData[ProcessorNumber], Procedure, ProcedureArgument);
+
+ if (WaitEvent != NULL) {
+ // Non Blocking
+ gMPSystem.WaitEvent = WaitEvent;
+ gBS->SetTimer (
+ gMPSystem.ProcessorData[ProcessorNumber].CheckThisAPEvent,
+ TimerPeriodic,
+ gPollInterval
+ );
+ return EFI_SUCCESS;
+ }
+
+ // Blocking
+ while (TRUE) {
+ gThread->MutexLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
+ if (gMPSystem.ProcessorData[ProcessorNumber].State == CPU_STATE_FINISHED) {
+ gMPSystem.ProcessorData[ProcessorNumber].State = CPU_STATE_IDLE;
+ gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
+ break;
+ }
+
+ gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
+
+ if ((TimeoutInMicroseconds != 0) && (Timeout == 0)) {
+ return EFI_TIMEOUT;
+ }
+
+ Timeout -= CalculateAndStallInterval (Timeout);
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+/**
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. This call can only be performed
+ by the current BSP.
+
+ This service switches the requested AP to be the BSP from that point onward.
+ This service changes the BSP for all purposes. The new BSP can take over the
+ execution of the old BSP and continue seamlessly from where the old one left
+ off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT
+ is signaled.
+
+ If the BSP cannot be switched prior to the return from this service, then
+ EFI_UNSUPPORTED must be returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an
+ enabled AP. Otherwise, it will be disabled.
+
+ @retval EFI_SUCCESS BSP successfully switched.
+ @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to
+ this service returning.
+ @retval EFI_UNSUPPORTED Switching the BSP is not supported.
+ @retval EFI_SUCCESS The calling processor is an AP.
+ @retval EFI_NOT_FOUND The processor with the handle specified by
+ ProcessorNumber does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or
+ a disabled AP.
+ @retval EFI_NOT_READY The specified AP is busy.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMpServicesSwitchBSP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableOldBSP
+ )
+{
+ UINTN Index;
+
+ if (!IsBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ProcessorNumber >= gMPSystem.NumberOfProcessors) {
+ return EFI_NOT_FOUND;
+ }
+
+ if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Index = 0; Index < gMPSystem.NumberOfProcessors; Index++) {
+ if ((gMPSystem.ProcessorData[Index].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) != 0) {
+ break;
+ }
+ }
+ ASSERT (Index != gMPSystem.NumberOfProcessors);
+
+ gThread->MutexLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
+ if (gMPSystem.ProcessorData[ProcessorNumber].State != CPU_STATE_IDLE) {
+ gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
+ return EFI_NOT_READY;
+ }
+ gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
+
+ // Skip for now as we need switch a bunch of stack stuff around and it's complex
+ // May not be worth it?
+ return EFI_NOT_READY;
+}
+
+
+/**
+ This service lets the caller enable or disable an AP from this point onward.
+ This service may only be called from the BSP.
+
+ This service allows the caller enable or disable an AP from this point onward.
+ The caller can optionally specify the health status of the AP by Health. If
+ an AP is being disabled, then the state of the disabled AP is implementation
+ dependent. If an AP is enabled, then the implementation must guarantee that a
+ complete initialization sequence is performed on the AP, so the AP is in a state
+ that is compatible with an MP operating system. This service may not be supported
+ after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled.
+
+ If the enable or disable AP operation cannot be completed prior to the return
+ from this service, then EFI_UNSUPPORTED must be returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+ @param[in] EnableAP Specifies the new state for the processor for
+ enabled, FALSE for disabled.
+ @param[in] HealthFlag If not NULL, a pointer to a value that specifies
+ the new health status of the AP. This flag
+ corresponds to StatusFlag defined in
+ EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only
+ the PROCESSOR_HEALTH_STATUS_BIT is used. All other
+ bits are ignored. If it is NULL, this parameter
+ is ignored.
+
+ @retval EFI_SUCCESS The specified AP was enabled or disabled successfully.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed
+ prior to this service returning.
+ @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported.
+ @retval EFI_DEVICE_ERROR The calling processor is an AP.
+ @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber
+ does not exist.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMpServicesEnableDisableAP (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ IN UINTN ProcessorNumber,
+ IN BOOLEAN EnableAP,
+ IN UINT32 *HealthFlag OPTIONAL
+ )
+{
+ if (!IsBSP ()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (ProcessorNumber >= gMPSystem.NumberOfProcessors) {
+ return EFI_NOT_FOUND;
+ }
+
+ if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ gThread->MutexLock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
+ if (gMPSystem.ProcessorData[ProcessorNumber].State != CPU_STATE_IDLE) {
+ gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
+ return EFI_UNSUPPORTED;
+ }
+ gThread->MutexUnlock (gMPSystem.ProcessorData[ProcessorNumber].StateLock);
+
+ if (EnableAP) {
+ if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0 ) {
+ gMPSystem.NumberOfEnabledProcessors++;
+ }
+ gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag |= PROCESSOR_ENABLED_BIT;
+ } else {
+ if ((gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag & PROCESSOR_ENABLED_BIT) == PROCESSOR_ENABLED_BIT ) {
+ gMPSystem.NumberOfEnabledProcessors--;
+ }
+ gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag &= ~PROCESSOR_ENABLED_BIT;
+ }
+
+ if (HealthFlag != NULL) {
+ gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag &= ~PROCESSOR_HEALTH_STATUS_BIT;
+ gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag |= (*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This return the handle number for the calling processor. This service may be
+ called from the BSP and APs.
+
+ This service returns the processor handle number for the calling processor.
+ The returned value is in the range from 0 to the total number of logical
+ processors minus 1. The total number of logical processors can be retrieved
+ with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be
+ called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER
+ is returned. Otherwise, the current processors handle number is returned in
+ ProcessorNumber, and EFI_SUCCESS is returned.
+
+ @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance.
+ @param[in] ProcessorNumber The handle number of AP that is to become the new
+ BSP. The range is from 0 to the total number of
+ logical processors minus 1. The total number of
+ logical processors can be retrieved by
+ EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors().
+
+ @retval EFI_SUCCESS The current processor handle number was returned
+ in ProcessorNumber.
+ @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMpServicesWhoAmI (
+ IN EFI_MP_SERVICES_PROTOCOL *This,
+ OUT UINTN *ProcessorNumber
+ )
+{
+ UINTN Index;
+ UINT64 ProcessorId;
+
+ if (ProcessorNumber == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ProcessorId = gThread->Self ();
+ for (Index = 0; Index < gMPSystem.NumberOfProcessors; Index++) {
+ if (gMPSystem.ProcessorData[Index].Info.ProcessorId == ProcessorId) {
+ break;
+ }
+ }
+
+ *ProcessorNumber = Index;
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = {
+ CpuMpServicesGetNumberOfProcessors,
+ CpuMpServicesGetProcessorInfo,
+ CpuMpServicesStartupAllAps,
+ CpuMpServicesStartupThisAP,
+ CpuMpServicesSwitchBSP,
+ CpuMpServicesEnableDisableAP,
+ CpuMpServicesWhoAmI
+};
+
+
+
+/*++
+ If timeout occurs in StartupAllAps(), a timer is set, which invokes this
+ procedure periodically to check whether all APs have finished.
+
+
+--*/
+VOID
+EFIAPI
+CpuCheckAllAPsStatus (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN ProcessorNumber;
+ UINTN NextNumber;
+ PROCESSOR_DATA_BLOCK *ProcessorData;
+ PROCESSOR_DATA_BLOCK *NextData;
+ EFI_STATUS Status;
+ PROCESSOR_STATE ProcessorState;
+ UINTN Cpu;
+ BOOLEAN Found;
+
+ if (gMPSystem.TimeoutActive) {
+ gMPSystem.Timeout -= CalculateAndStallInterval (gMPSystem.Timeout);
+ }
+
+ for (ProcessorNumber = 0; ProcessorNumber < gMPSystem.NumberOfProcessors; ProcessorNumber++) {
+ ProcessorData = &gMPSystem.ProcessorData[ProcessorNumber];
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
+ // Skip BSP
+ continue;
+ }
+
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
+ // Skip Disabled processors
+ continue;
+ }
+
+ // This is an Interrupt Service routine.
+ // This can grab a lock that is held in a non-interrupt
+ // context. Meaning deadlock. Which is a bad thing.
+ // So, try lock it. If we can get it, cool, do our thing.
+ // otherwise, just dump out & try again on the next iteration.
+ Status = gThread->MutexTryLock (ProcessorData->StateLock);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ ProcessorState = ProcessorData->State;
+ gThread->MutexUnlock (ProcessorData->StateLock);
+
+ switch (ProcessorState) {
+ case CPU_STATE_FINISHED:
+ if (gMPSystem.SingleThread) {
+ Status = GetNextBlockedNumber (&NextNumber);
+ if (!EFI_ERROR (Status)) {
+ NextData = &gMPSystem.ProcessorData[NextNumber];
+
+ gThread->MutexLock (NextData->StateLock);
+ NextData->State = CPU_STATE_READY;
+ gThread->MutexUnlock (NextData->StateLock);
+
+ SetApProcedure (NextData, gMPSystem.Procedure, gMPSystem.ProcedureArgument);
+ }
+ }
+
+ gThread->MutexLock (ProcessorData->StateLock);
+ ProcessorData->State = CPU_STATE_IDLE;
+ gThread->MutexUnlock (ProcessorData->StateLock);
+ gMPSystem.FinishCount++;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (gMPSystem.TimeoutActive && gMPSystem.Timeout == 0) {
+ //
+ // Timeout
+ //
+ if (gMPSystem.FailedList != NULL) {
+ for (ProcessorNumber = 0; ProcessorNumber < gMPSystem.NumberOfProcessors; ProcessorNumber++) {
+ ProcessorData = &gMPSystem.ProcessorData[ProcessorNumber];
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
+ // Skip BSP
+ continue;
+ }
+
+ if ((ProcessorData->Info.StatusFlag & PROCESSOR_ENABLED_BIT) == 0) {
+ // Skip Disabled processors
+ continue;
+ }
+
+ // Mark the
+ Status = gThread->MutexTryLock (ProcessorData->StateLock);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ ProcessorState = ProcessorData->State;
+ gThread->MutexUnlock (ProcessorData->StateLock);
+
+ if (ProcessorState != CPU_STATE_IDLE) {
+ // If we are retrying make sure we don't double count
+ for (Cpu = 0, Found = FALSE; Cpu < gMPSystem.NumberOfProcessors; Cpu++) {
+ if (gMPSystem.FailedList[Cpu] == END_OF_CPU_LIST) {
+ break;
+ }
+ if (gMPSystem.FailedList[ProcessorNumber] == Cpu) {
+ Found = TRUE;
+ break;
+ }
+ }
+ if (!Found) {
+ gMPSystem.FailedList[gMPSystem.FailedListIndex++] = Cpu;
+ }
+ }
+ }
+ }
+ // Force terminal exit
+ gMPSystem.FinishCount = gMPSystem.StartCount;
+ }
+
+ if (gMPSystem.FinishCount != gMPSystem.StartCount) {
+ return;
+ }
+
+ gBS->SetTimer (
+ gMPSystem.CheckAllAPsEvent,
+ TimerCancel,
+ 0
+ );
+
+ if (gMPSystem.FailedListIndex == 0) {
+ if (gMPSystem.FailedList != NULL) {
+ FreePool (gMPSystem.FailedList);
+ gMPSystem.FailedList = NULL;
+ }
+ }
+
+ Status = gBS->SignalEvent (gMPSystem.WaitEvent);
+
+ return ;
+}
+
+VOID
+EFIAPI
+CpuCheckThisAPStatus (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ PROCESSOR_DATA_BLOCK *ProcessorData;
+ PROCESSOR_STATE ProcessorState;
+
+ ProcessorData = (PROCESSOR_DATA_BLOCK *) Context;
+
+ //
+ // This is an Interrupt Service routine.
+ // that can grab a lock that is held in a non-interrupt
+ // context. Meaning deadlock. Which is a badddd thing.
+ // So, try lock it. If we can get it, cool, do our thing.
+ // otherwise, just dump out & try again on the next iteration.
+ //
+ Status = gThread->MutexTryLock (ProcessorData->StateLock);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ ProcessorState = ProcessorData->State;
+ gThread->MutexUnlock (ProcessorData->StateLock);
+
+ if (ProcessorState == CPU_STATE_FINISHED) {
+ Status = gBS->SetTimer (ProcessorData->CheckThisAPEvent, TimerCancel, 0);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->SignalEvent (gMPSystem.WaitEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ gThread->MutexLock (ProcessorData->StateLock);
+ ProcessorData->State = CPU_STATE_IDLE;
+ gThread->MutexUnlock (ProcessorData->StateLock);
+ }
+
+ return ;
+}
+
+
+/*++
+ This function is called by all processors (both BSP and AP) once and collects MP related data
+
+ MPSystemData - Pointer to the data structure containing MP related data
+ BSP - TRUE if the CPU is BSP
+
+ EFI_SUCCESS - Data for the processor collected and filled in
+
+--*/
+EFI_STATUS
+FillInProcessorInformation (
+ IN BOOLEAN BSP,
+ IN UINTN ProcessorNumber
+ )
+{
+ gMPSystem.ProcessorData[ProcessorNumber].Info.ProcessorId = gThread->Self ();
+ gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;
+ if (BSP) {
+ gMPSystem.ProcessorData[ProcessorNumber].Info.StatusFlag |= PROCESSOR_AS_BSP_BIT;
+ }
+
+ gMPSystem.ProcessorData[ProcessorNumber].Info.Location.Package = (UINT32) ProcessorNumber;
+ gMPSystem.ProcessorData[ProcessorNumber].Info.Location.Core = 0;
+ gMPSystem.ProcessorData[ProcessorNumber].Info.Location.Thread = 0;
+ gMPSystem.ProcessorData[ProcessorNumber].State = BSP ? CPU_STATE_BUSY : CPU_STATE_IDLE;
+
+ gMPSystem.ProcessorData[ProcessorNumber].Procedure = NULL;
+ gMPSystem.ProcessorData[ProcessorNumber].Parameter = NULL;
+ gMPSystem.ProcessorData[ProcessorNumber].StateLock = gThread->MutexInit ();
+ gMPSystem.ProcessorData[ProcessorNumber].ProcedureLock = gThread->MutexInit ();
+
+ return EFI_SUCCESS;
+}
+
+VOID *
+EFIAPI
+CpuDriverApIdolLoop (
+ VOID *Context
+ )
+{
+ EFI_AP_PROCEDURE Procedure;
+ VOID *Parameter;
+ UINTN ProcessorNumber;
+ PROCESSOR_DATA_BLOCK *ProcessorData;
+
+ ProcessorNumber = (UINTN)Context;
+ ProcessorData = &gMPSystem.ProcessorData[ProcessorNumber];
+
+ ProcessorData->Info.ProcessorId = gThread->Self ();
+
+ while (TRUE) {
+ //
+ // Make a local copy on the stack to be extra safe
+ //
+ gThread->MutexLock (ProcessorData->ProcedureLock);
+ Procedure = ProcessorData->Procedure;
+ Parameter = ProcessorData->Parameter;
+ gThread->MutexUnlock (ProcessorData->ProcedureLock);
+
+ if (Procedure != NULL) {
+ gThread->MutexLock (ProcessorData->StateLock);
+ ProcessorData->State = CPU_STATE_BUSY;
+ gThread->MutexUnlock (ProcessorData->StateLock);
+
+ Procedure (Parameter);
+
+ gThread->MutexLock (ProcessorData->ProcedureLock);
+ ProcessorData->Procedure = NULL;
+ gThread->MutexUnlock (ProcessorData->ProcedureLock);
+
+ gThread->MutexLock (ProcessorData->StateLock);
+ ProcessorData->State = CPU_STATE_FINISHED;
+ gThread->MutexUnlock (ProcessorData->StateLock);
+ }
+
+ // Poll 5 times a seconds, 200ms
+ // Don't want to burn too many system resources doing nothing.
+ gEmuThunk->Sleep (200 * 1000);
+ }
+
+ return 0;
+}
+
+
+EFI_STATUS
+InitializeMpSystemData (
+ IN UINTN NumberOfProcessors
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+
+
+ //
+ // Clear the data structure area first.
+ //
+ ZeroMem (&gMPSystem, sizeof (MP_SYSTEM_DATA));
+
+ //
+ // First BSP fills and inits all known values, including it's own records.
+ //
+ gMPSystem.NumberOfProcessors = NumberOfProcessors;
+ gMPSystem.NumberOfEnabledProcessors = NumberOfProcessors;
+
+ gMPSystem.ProcessorData = AllocateZeroPool (gMPSystem.NumberOfProcessors * sizeof (PROCESSOR_DATA_BLOCK));
+ ASSERT (gMPSystem.ProcessorData != NULL);
+
+ FillInProcessorInformation (TRUE, 0);
+
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ CpuCheckAllAPsStatus,
+ NULL,
+ &gMPSystem.CheckAllAPsEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ for (Index = 0; Index < gMPSystem.NumberOfProcessors; Index++) {
+ if ((gMPSystem.ProcessorData[Index].Info.StatusFlag & PROCESSOR_AS_BSP_BIT) == PROCESSOR_AS_BSP_BIT) {
+ // Skip BSP
+ continue;
+ }
+
+ FillInProcessorInformation (FALSE, Index);
+
+ Status = gThread->CreateThread (
+ (VOID *)&gMPSystem.ProcessorData[Index].Info.ProcessorId,
+ NULL,
+ CpuDriverApIdolLoop,
+ (VOID *)Index
+ );
+
+
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ CpuCheckThisAPStatus,
+ (VOID *) &gMPSystem.ProcessorData[Index],
+ &gMPSystem.ProcessorData[Index].CheckThisAPEvent
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+
+/**
+ Invoke a notification event
+
+ @param Event Event whose notification function is being invoked.
+ @param Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+CpuReadToBootFunction (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ gReadToBoot = TRUE;
+}
+
+
+
+EFI_STATUS
+CpuMpServicesInit (
+ OUT UINTN *MaxCpus
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EMU_IO_THUNK_PROTOCOL *IoThunk;
+
+ *MaxCpus = 1; // BSP
+ IoThunk = GetIoThunkInstance (&gEmuThreadThunkProtocolGuid, 0);
+ if (IoThunk != NULL) {
+ Status = IoThunk->Open (IoThunk);
+ if (!EFI_ERROR (Status)) {
+ if (IoThunk->ConfigString != NULL) {
+ *MaxCpus += StrDecimalToUintn (IoThunk->ConfigString);
+ gThread = IoThunk->Interface;
+ }
+ }
+ }
+
+ if (*MaxCpus == 1) {
+ // We are not MP so nothing to do
+ return EFI_SUCCESS;
+ }
+
+ gPollInterval = (UINTN) PcdGet64 (PcdEmuMpServicesPollingInterval);
+
+ Status = InitializeMpSystemData (*MaxCpus);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = EfiCreateEventReadyToBootEx (TPL_CALLBACK, CpuReadToBootFunction, NULL, &gReadToBootEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Now install the MP services protocol.
+ //
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiMpServiceProtocolGuid, &mMpServicesTemplate,
+ NULL
+ );
+ return Status;
+}
+
+
diff --git a/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/ComponentName.c b/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/ComponentName.c
new file mode 100644
index 00000000000..d0ded4b6eae
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/ComponentName.c
@@ -0,0 +1,348 @@
+/**@file
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+**/
+
+#include "EmuBlockIo.h"
+
+//
+// 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
+EmuBlockIoComponentNameGetDriverName (
+ 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
+EmuBlockIoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gEmuBlockIoComponentName = {
+ EmuBlockIoComponentNameGetDriverName,
+ EmuBlockIoComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gEmuBlockIoComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) EmuBlockIoComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) EmuBlockIoComponentNameGetControllerName,
+ "en"
+};
+
+
+EFI_UNICODE_STRING_TABLE mEmuBlockIoDriverNameTable[] = {
+ { "eng;en", L"Emu Block I/O Driver" },
+ { 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
+EmuBlockIoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mEmuBlockIoDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gEmuBlockIoComponentName)
+ );
+}
+
+/**
+ 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
+EmuBlockIoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EMU_BLOCK_IO_PRIVATE *Private;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Make sure this driver is currently managing ControllerHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ gEmuBlockIoDriverBinding.DriverBindingHandle,
+ &gEmuIoThunkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiBlockIoProtocolGuid,
+ (VOID **)&BlockIo,
+ gEmuBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo);
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ Private->ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gEmuBlockIoComponentName)
+ );
+}
diff --git a/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/DriverConfiguration.c b/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/DriverConfiguration.c
new file mode 100644
index 00000000000..b6a2ff471d7
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/DriverConfiguration.c
@@ -0,0 +1,332 @@
+/**@file
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+ DriverConfiguration.c
+
+Abstract:
+
+**/
+
+#include "EmuBlockIo.h"
+
+//
+// EFI Driver Configuration Functions
+//
+EFI_STATUS
+EFIAPI
+EmuBlockIoDriverConfigurationSetOptions (
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired
+ );
+
+EFI_STATUS
+EFIAPI
+EmuBlockIoDriverConfigurationOptionsValid (
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL
+ );
+
+EFI_STATUS
+EFIAPI
+EmuBlockIoDriverConfigurationForceDefaults (
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN UINT32 DefaultType,
+ OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired
+ );
+
+//
+// EFI Driver Configuration Protocol
+//
+EFI_DRIVER_CONFIGURATION_PROTOCOL gEmuBlockIoDriverConfiguration = {
+ EmuBlockIoDriverConfigurationSetOptions,
+ EmuBlockIoDriverConfigurationOptionsValid,
+ EmuBlockIoDriverConfigurationForceDefaults,
+ "eng"
+};
+
+/*++
+
+ Routine Description:
+ Allows the user to set controller specific options for a controller that a
+ driver is currently managing.
+
+ Arguments:
+ This - A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.
+ ControllerHandle - The handle of the controller to set options on.
+ ChildHandle - The handle of the child controller to set options on. This
+ is an optional parameter that may be NULL. It will be NULL
+ for device drivers, and for a bus drivers that wish to set
+ options for the bus controller. It will not be NULL for a
+ bus driver that wishes to set options for one of its child
+ controllers.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the user interface that should be
+ presented to the user, 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.
+ ActionRequired - A pointer to the action that the calling agent is required
+ to perform when this function returns. See "Related
+ Definitions" for a list of the actions that the calling
+ agent is required to perform prior to accessing
+ ControllerHandle again.
+
+ Returns:
+ EFI_SUCCESS - The driver specified by This successfully set the
+ configuration options for the controller specified
+ by ControllerHandle..
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ActionRequired is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support setting
+ configuration options for the controller specified by
+ ControllerHandle and ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+ EFI_DEVICE_ERROR - A device error occurred while attempt to set the
+ configuration options for the controller specified
+ by ControllerHandle and ChildHandle.
+ EFI_OUT_RESOURCES - There are not enough resources available to set the
+ configuration options for the controller specified
+ by ControllerHandle and ChildHandle.
+
+--*/
+EFI_STATUS
+EFIAPI
+EmuBlockIoDriverConfigurationSetOptions (
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired
+ )
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ CHAR8 *SupportedLanguage;
+
+ SupportedLanguage = This->SupportedLanguages;
+
+ Status = EFI_UNSUPPORTED;
+ while (*SupportedLanguage != 0) {
+ if (AsciiStrnCmp (Language, SupportedLanguage, 3) == 0) {
+ Status = EFI_SUCCESS;
+ }
+
+ SupportedLanguage += 3;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (ActionRequired == NULL || ControllerHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Validate controller handle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&BlockIo,
+ gEmuBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ gEmuBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Status == EFI_UNSUPPORTED) {
+ return Status;
+ } else if (Status != EFI_ALREADY_STARTED) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *ActionRequired = EfiDriverConfigurationActionNone;
+ return EFI_SUCCESS;
+}
+
+/*++
+
+ Routine Description:
+ Tests to see if a controller's current configuration options are valid.
+
+ Arguments:
+ This - A pointer to the EFI_DRIVER_CONFIGURATION_PROTOCOL instance.
+ ControllerHandle - The handle of the controller to test if it's current
+ configuration options are valid.
+ ChildHandle - The handle of the child controller to test if it's current
+ configuration options are valid. 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 test the configuration options for the bus controller.
+ It will not be NULL for a bus driver that wishes to test
+ configuration options for one of its child controllers.
+
+ Returns:
+ EFI_SUCCESS - The controller specified by ControllerHandle and
+ ChildHandle that is being managed by the driver
+ specified by This has a valid set of configuration
+ options.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_UNSUPPORTED - The driver specified by This is not currently
+ managing the controller specified by ControllerHandle
+ and ChildHandle.
+ EFI_DEVICE_ERROR - The controller specified by ControllerHandle and
+ ChildHandle that is being managed by the driver
+ specified by This has an invalid set of configuration
+ options.
+
+--*/
+EFI_STATUS
+EFIAPI
+EmuBlockIoDriverConfigurationOptionsValid (
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (ControllerHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Validate controller handle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&BlockIo,
+ gEmuBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ gEmuBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Status == EFI_UNSUPPORTED) {
+ return Status;
+ } else if (Status != EFI_ALREADY_STARTED) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/*++
+
+ Routine Description:
+ Forces a driver to set the default configuration options for a controller.
+
+ Arguments:
+ This - A pointer to the EFI_DRIVER_CONFIGURATION_ PROTOCOL instance.
+ ControllerHandle - The handle of the controller to force default configuration options on.
+ ChildHandle - The handle of the child controller to force default configuration options on 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 force default configuration options for the bus controller. It will not be NULL for a bus driver that wishes to force default configuration options for one of its child controllers.
+ DefaultType - The type of default configuration options to force on the controller specified by ControllerHandle and ChildHandle. See Table 9-1 for legal values. A DefaultType of 0x00000000 must be supported by this protocol.
+ ActionRequired - A pointer to the action that the calling agent is required to perform when this function returns. See "Related Definitions" in Section 9.1for a list of the actions that the calling agent is required to perform prior to accessing ControllerHandle again.
+
+ Returns:
+ EFI_SUCCESS - The driver specified by This successfully forced the default configuration options on the controller specified by ControllerHandle and ChildHandle.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ActionRequired is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support forcing the default configuration options on the controller specified by ControllerHandle and ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the configuration type specified by DefaultType.
+ EFI_DEVICE_ERROR - A device error occurred while attempt to force the default configuration options on the controller specified by ControllerHandle and ChildHandle.
+ EFI_OUT_RESOURCES - There are not enough resources available to force the default configuration options on the controller specified by ControllerHandle and ChildHandle.
+
+--*/
+EFI_STATUS
+EFIAPI
+EmuBlockIoDriverConfigurationForceDefaults (
+ IN EFI_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN UINT32 DefaultType,
+ OUT EFI_DRIVER_CONFIGURATION_ACTION_REQUIRED *ActionRequired
+ )
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (ActionRequired == NULL || ControllerHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Validate controller handle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&BlockIo,
+ gEmuBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ gEmuBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Status == EFI_UNSUPPORTED) {
+ return Status;
+ } else if (Status != EFI_ALREADY_STARTED) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *ActionRequired = EfiDriverConfigurationActionNone;
+ return EFI_SUCCESS;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/DriverDiagnostics.c b/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/DriverDiagnostics.c
new file mode 100644
index 00000000000..3e7604fbee1
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/DriverDiagnostics.c
@@ -0,0 +1,213 @@
+/**@file
+
+Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+ DriverDiagnostics.c
+
+Abstract:
+
+**/
+
+#include "EmuBlockIo.h"
+
+//
+// EFI Driver Diagnostics Functions
+//
+EFI_STATUS
+EFIAPI
+EmuBlockIoDriverDiagnosticsRunDiagnostics (
+ IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType,
+ IN CHAR8 *Language,
+ OUT EFI_GUID **ErrorType,
+ OUT UINTN *BufferSize,
+ OUT CHAR16 **Buffer
+ );
+
+//
+// EFI Driver Diagnostics Protocol
+//
+EFI_DRIVER_DIAGNOSTICS_PROTOCOL gEmuBlockIoDriverDiagnostics = {
+ EmuBlockIoDriverDiagnosticsRunDiagnostics,
+ "eng"
+};
+
+//
+// EFI Driver Diagnostics 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DRIVER_DIAGNOSTICS2_PROTOCOL gEmuBlockIoDriverDiagnostics2 = {
+ (EFI_DRIVER_DIAGNOSTICS2_RUN_DIAGNOSTICS) EmuBlockIoDriverDiagnosticsRunDiagnostics,
+ "en"
+};
+
+EFI_STATUS
+EFIAPI
+EmuBlockIoDriverDiagnosticsRunDiagnostics (
+ IN EFI_DRIVER_DIAGNOSTICS_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN EFI_DRIVER_DIAGNOSTIC_TYPE DiagnosticType,
+ IN CHAR8 *Language,
+ OUT EFI_GUID **ErrorType,
+ OUT UINTN *BufferSize,
+ OUT CHAR16 **Buffer
+ )
+/*++
+
+ Routine Description:
+ Runs diagnostics on a controller.
+
+ Arguments:
+ This - A pointer to the EFI_DRIVER_DIAGNOSTICS_PROTOCOL instance.
+ ControllerHandle - The handle of the controller to run diagnostics on.
+ ChildHandle - The handle of the child controller to run diagnostics on
+ 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 run diagnostics on the bus
+ controller. It will not be NULL for a bus driver that
+ wishes to run diagnostics on one of its child controllers.
+ DiagnosticType - Indicates type of diagnostics to perform on the controller
+ specified by ControllerHandle and ChildHandle. See
+ "Related Definitions" for the list of supported types.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier or a Null-terminated ASCII string array indicating
+ the language. This is the language in which the optional
+ error message should be returned in Buffer, 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.
+ ErrorType - A GUID that defines the format of the data returned in
+ Buffer.
+ BufferSize - The size, in bytes, of the data returned in Buffer.
+ Buffer - A buffer that contains a Null-terminated Unicode string
+ plus some additional data whose format is defined by
+ ErrorType. Buffer is allocated by this function with
+ AllocatePool(), and it is the caller's responsibility
+ to free it with a call to FreePool().
+
+ Returns:
+ EFI_SUCCESS - The controller specified by ControllerHandle and
+ ChildHandle passed the diagnostic.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ErrorType is NULL.
+ EFI_INVALID_PARAMETER - BufferType is NULL.
+ EFI_INVALID_PARAMETER - Buffer is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support
+ running diagnostics for the controller specified
+ by ControllerHandle and ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ type of diagnostic specified by DiagnosticType.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+ EFI_OUT_OF_RESOURCES - There are not enough resources available to complete
+ the diagnostics.
+ EFI_OUT_OF_RESOURCES - There are not enough resources available to return
+ the status information in ErrorType, BufferSize,
+ and Buffer.
+ EFI_DEVICE_ERROR - The controller specified by ControllerHandle and
+ ChildHandle did not pass the diagnostic.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ CHAR8 *SupportedLanguages;
+ BOOLEAN Iso639Language;
+ BOOLEAN Found;
+ UINTN Index;
+
+ if (Language == NULL ||
+ ErrorType == NULL ||
+ Buffer == NULL ||
+ ControllerHandle == NULL ||
+ BufferSize == NULL) {
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SupportedLanguages = This->SupportedLanguages;
+ Iso639Language = (BOOLEAN)(This == &gEmuBlockIoDriverDiagnostics);
+ //
+ // Make sure Language is in the set of Supported Languages
+ //
+ Found = FALSE;
+ while (*SupportedLanguages != 0) {
+ if (Iso639Language) {
+ if (CompareMem (Language, SupportedLanguages, 3) == 0) {
+ Found = TRUE;
+ break;
+ }
+ SupportedLanguages += 3;
+ } else {
+ for (Index = 0; SupportedLanguages[Index] != 0 && SupportedLanguages[Index] != ';'; Index++);
+ if ((AsciiStrnCmp(SupportedLanguages, Language, Index) == 0) && (Language[Index] == 0)) {
+ Found = TRUE;
+ break;
+ }
+ SupportedLanguages += Index;
+ for (; *SupportedLanguages != 0 && *SupportedLanguages == ';'; SupportedLanguages++);
+ }
+ }
+ //
+ // If Language is not a member of SupportedLanguages, then return EFI_UNSUPPORTED
+ //
+ if (!Found) {
+ return EFI_UNSUPPORTED;
+ }
+
+ *ErrorType = NULL;
+ *BufferSize = 0;
+ if (DiagnosticType != EfiDriverDiagnosticTypeStandard) {
+ *ErrorType = &gEfiBlockIoProtocolGuid;
+ *BufferSize = 0x60;
+ Buffer = AllocatePool ((UINTN) (*BufferSize));
+ CopyMem (*Buffer, L"Windows Block I/O Driver Diagnostics Failed\n", *BufferSize);
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Validate controller handle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&BlockIo,
+ gEmuBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ gEmuBlockIoDriverBinding.DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Status == EFI_UNSUPPORTED) {
+ return Status;
+ } else if (Status != EFI_ALREADY_STARTED) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/EmuBlockIo.c b/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/EmuBlockIo.c
new file mode 100644
index 00000000000..5a38fcd854e
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/EmuBlockIo.c
@@ -0,0 +1,743 @@
+/**@file
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+bbe
+**/
+
+#include "EmuBlockIo.h"
+
+
+/**
+ Reset the block device hardware.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] ExtendedVerification Indicates that the driver may perform a more
+ exhausive verfication operation of the device
+ during reset.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could
+ not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuBlockIo2Reset (
+ IN EFI_BLOCK_IO2_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ EFI_STATUS Status;
+ EMU_BLOCK_IO_PRIVATE *Private;
+ EFI_TPL OldTpl;
+
+ Private = EMU_BLOCK_IO2_PRIVATE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Status = Private->Io->Reset (Private->Io, ExtendedVerification);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Read BufferSize bytes from Lba into Buffer.
+
+ This function reads the requested number of blocks from the device. All the
+ blocks are read, or an error is returned.
+ If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_or EFI_MEDIA_CHANGED is returned and
+ non-blocking I/O is being used, the Event associated with this request will
+ not be signaled.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] MediaId Id of the media, changes every time the media is
+ replaced.
+ @param[in] Lba The starting Logical Block Address to read from.
+ @param[in, out] Token A pointer to the token associated with the transaction.
+ @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
+ @param[out] Buffer A pointer to the destination buffer for the data. The
+ caller is responsible for either having implicit or
+ explicit ownership of the buffer.
+
+ @retval EFI_SUCCESS The read request was queued if Token->Event is
+ not NULL.The data was read correctly from the
+ device if the Token->Event is NULL.
+ @retval EFI_DEVICE_ERROR The device reported an error while performing
+ the read.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
+ @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
+ intrinsic block size of the device.
+ @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
+ or the buffer is not on proper alignment.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
+ of resources.
+**/
+EFI_STATUS
+EFIAPI
+EmuBlockIo2ReadBlocksEx (
+ IN EFI_BLOCK_IO2_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN OUT EFI_BLOCK_IO2_TOKEN *Token,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ EMU_BLOCK_IO_PRIVATE *Private;
+ EFI_TPL OldTpl;
+
+ Private = EMU_BLOCK_IO2_PRIVATE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Status = Private->Io->ReadBlocks (Private->Io, MediaId, LBA, Token, BufferSize, Buffer);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+/**
+ Write BufferSize bytes from Lba into Buffer.
+
+ This function writes the requested number of blocks to the device. All blocks
+ are written, or an error is returned.If EFI_DEVICE_ERROR, EFI_NO_MEDIA,
+ EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED is returned and non-blocking I/O is
+ being used, the Event associated with this request will not be signaled.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] MediaId The media ID that the write request is for.
+ @param[in] Lba The starting logical block address to be written. The
+ caller is responsible for writing to only legitimate
+ locations.
+ @param[in, out] Token A pointer to the token associated with the transaction.
+ @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
+ @param[in] Buffer A pointer to the source buffer for the data.
+
+ @retval EFI_SUCCESS The write request was queued if Event is not NULL.
+ The data was written correctly to the device if
+ the Event is NULL.
+ @retval EFI_WRITE_PROTECTED The device can not be written to.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
+ @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
+ or the buffer is not on proper alignment.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
+ of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuBlockIo2WriteBlocksEx (
+ IN EFI_BLOCK_IO2_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN OUT EFI_BLOCK_IO2_TOKEN *Token,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ EMU_BLOCK_IO_PRIVATE *Private;
+ EFI_TPL OldTpl;
+
+ Private = EMU_BLOCK_IO2_PRIVATE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Status = Private->Io->WriteBlocks (Private->Io, MediaId, LBA, Token, BufferSize, Buffer);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+
+/**
+ Flush the Block Device.
+
+ If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED
+ is returned and non-blocking I/O is being used, the Event associated with
+ this request will not be signaled.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in,out] Token A pointer to the token associated with the transaction
+
+ @retval EFI_SUCCESS The flush request was queued if Event is not NULL.
+ All outstanding data was written correctly to the
+ device if the Event is NULL.
+ @retval EFI_DEVICE_ERROR The device reported an error while writting back
+ the data.
+ @retval EFI_WRITE_PROTECTED The device cannot be written to.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
+ of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuBlockIo2Flush (
+ IN EFI_BLOCK_IO2_PROTOCOL *This,
+ IN OUT EFI_BLOCK_IO2_TOKEN *Token
+ )
+{
+ EFI_STATUS Status;
+ EMU_BLOCK_IO_PRIVATE *Private;
+ EFI_TPL OldTpl;
+
+ Private = EMU_BLOCK_IO2_PRIVATE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Status = Private->Io->FlushBlocks (Private->Io, Token);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+
+/**
+ Reset the Block Device.
+
+ @param This Indicates a pointer to the calling context.
+ @param ExtendedVerification Driver may perform diagnostics on reset.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could
+ not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuBlockIoReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ EFI_STATUS Status;
+ EMU_BLOCK_IO_PRIVATE *Private;
+ EFI_TPL OldTpl;
+
+ Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Status = Private->Io->Reset (Private->Io, ExtendedVerification);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+/**
+ Read BufferSize bytes from Lba into Buffer.
+
+ @param This Indicates a pointer to the calling context.
+ @param MediaId Id of the media, changes every time the media is replaced.
+ @param Lba The starting Logical Block Address to read from
+ @param BufferSize Size of Buffer, must be a multiple of device block size.
+ @param Buffer A pointer to the destination buffer for the data. The caller is
+ responsible for either having implicit or explicit ownership of the buffer.
+
+ @retval EFI_SUCCESS The data was read correctly from the device.
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
+ @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
+ or the buffer is not on proper alignment.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuBlockIoReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ EMU_BLOCK_IO_PRIVATE *Private;
+ EFI_TPL OldTpl;
+ EFI_BLOCK_IO2_TOKEN Token;
+
+ Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Token.Event = NULL;
+ Status = Private->Io->ReadBlocks (Private->Io, MediaId, Lba, &Token, BufferSize, Buffer);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+/**
+ Write BufferSize bytes from Lba into Buffer.
+
+ @param This Indicates a pointer to the calling context.
+ @param MediaId The media ID that the write request is for.
+ @param Lba The starting logical block address to be written. The caller is
+ responsible for writing to only legitimate locations.
+ @param BufferSize Size of Buffer, must be a multiple of device block size.
+ @param Buffer A pointer to the source buffer for the data.
+
+ @retval EFI_SUCCESS The data was written correctly to the device.
+ @retval EFI_WRITE_PROTECTED The device can not be written to.
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
+ @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
+ or the buffer is not on proper alignment.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuBlockIoWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ EMU_BLOCK_IO_PRIVATE *Private;
+ EFI_TPL OldTpl;
+ EFI_BLOCK_IO2_TOKEN Token;
+
+ Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Token.Event = NULL;
+ Status = Private->Io->WriteBlocks (Private->Io, MediaId, Lba, &Token, BufferSize, Buffer);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Flush the Block Device.
+
+ @param This Indicates a pointer to the calling context.
+
+ @retval EFI_SUCCESS All outstanding data was written to the device
+ @retval EFI_DEVICE_ERROR The device reported an error while writting back the data
+ @retval EFI_NO_MEDIA There is no media in the device.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuBlockIoFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ EMU_BLOCK_IO_PRIVATE *Private;
+ EFI_TPL OldTpl;
+ EFI_BLOCK_IO2_TOKEN Token;
+
+ Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Token.Event = NULL;
+ Status = Private->Io->FlushBlocks (Private->Io, &Token);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+
+/**
+ Tests to see if this driver supports a given controller. If a child device is provided,
+ it further tests to see if this driver supports creating a handle for the specified child device.
+
+ This function checks to see if the driver specified by This supports the device specified by
+ ControllerHandle. Drivers will typically use the device path attached to
+ ControllerHandle and/or the services from the bus I/O abstraction attached to
+ ControllerHandle to determine if the driver supports ControllerHandle. This function
+ may be called many times during platform initialization. In order to reduce boot times, the tests
+ performed by this function must be very small, and take as little time as possible to execute. This
+ function must not change the state of any hardware devices, and this function must be aware that the
+ device specified by ControllerHandle may already be managed by the same driver or a
+ different driver. This function must match its calls to AllocatePages() with FreePages(),
+ AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
+ Because ControllerHandle may have been previously started by the same driver, if a protocol is
+ already in the opened state, then it must not be closed with CloseProtocol(). This is required
+ to guarantee the state of ControllerHandle is not modified by this function.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to test. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For bus drivers, if this parameter is not NULL, then
+ the bus driver must determine if the bus controller specified
+ by ControllerHandle and the child controller specified
+ by RemainingDevicePath are both supported by this
+ bus driver.
+
+ @retval EFI_SUCCESS The device specified by ControllerHandle and
+ RemainingDevicePath is supported by the driver specified by This.
+ @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by the driver
+ specified by This.
+ @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by a different
+ driver or an application that requires exclusive access.
+ Currently not implemented.
+ @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
+ RemainingDevicePath is not supported by the driver specified by This.
+**/
+EFI_STATUS
+EFIAPI
+EmuBlockIoDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&EmuIoThunk,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Make sure GUID is for a File System handle.
+ //
+ Status = EFI_UNSUPPORTED;
+ if (CompareGuid (EmuIoThunk->Protocol, &gEmuBlockIoProtocolGuid)) {
+ Status = EFI_SUCCESS;
+ }
+
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ Handle,
+ &gEmuIoThunkProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+ return Status;
+}
+
+
+/**
+ Starts a device controller or a bus controller.
+
+ The Start() function is designed to be invoked from the EFI boot service ConnectController().
+ As a result, much of the error checking on the parameters to Start() has been moved into this
+ common boot service. It is legal to call Start() from other locations,
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE.
+ 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
+ EFI_DEVICE_PATH_PROTOCOL.
+ 3. Prior to calling Start(), the Supported() function for the driver specified by This must
+ have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to start. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For a bus driver, if this parameter is NULL, then handles
+ for all the children of Controller are created by this driver.
+ If this parameter is not NULL and the first Device Path Node is
+ not the End of Device Path Node, then only the handle for the
+ child device specified by the first Device Path Node of
+ RemainingDevicePath is created by this driver.
+ If the first Device Path Node of RemainingDevicePath is
+ the End of Device Path Node, no child handle is created by this
+ driver.
+
+ @retval EFI_SUCCESS The device was started.
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval Others The driver failded to start the device.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuBlockIoDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
+ EMU_BLOCK_IO_PRIVATE *Private = NULL;
+
+ //
+ // Grab the protocols we need
+ //
+
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEmuIoThunkProtocolGuid,
+ (void *)&EmuIoThunk,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (!CompareGuid (EmuIoThunk->Protocol, &gEmuBlockIoProtocolGuid)) {
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
+
+ Status = EmuIoThunk->Open (EmuIoThunk);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Private = AllocatePool (sizeof (EMU_BLOCK_IO_PRIVATE));
+ if (Private == NULL) {
+ goto Done;
+ }
+
+ Private->Signature = EMU_BLOCK_IO_PRIVATE_SIGNATURE;
+ Private->IoThunk = EmuIoThunk;
+ Private->Io = EmuIoThunk->Interface;
+ Private->EfiHandle = Handle;
+
+ Private->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION2;
+ Private->BlockIo.Media = &Private->Media;
+ Private->BlockIo.Reset = EmuBlockIoReset;
+ Private->BlockIo.ReadBlocks = EmuBlockIoReadBlocks;
+ Private->BlockIo.WriteBlocks = EmuBlockIoWriteBlocks;
+ Private->BlockIo.FlushBlocks = EmuBlockIoFlushBlocks;
+
+ Private->BlockIo2.Media = &Private->Media;
+ Private->BlockIo2.Reset = EmuBlockIo2Reset;
+ Private->BlockIo2.ReadBlocksEx = EmuBlockIo2ReadBlocksEx;
+ Private->BlockIo2.WriteBlocksEx = EmuBlockIo2WriteBlocksEx;
+ Private->BlockIo2.FlushBlocksEx = EmuBlockIo2Flush;
+
+ Private->ControllerNameTable = NULL;
+
+ Status = Private->Io->CreateMapping (Private->Io, &Private->Media);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ AddUnicodeString2 (
+ "eng",
+ gEmuBlockIoComponentName.SupportedLanguages,
+ &Private->ControllerNameTable,
+ EmuIoThunk->ConfigString,
+ TRUE
+ );
+
+ AddUnicodeString2 (
+ "en",
+ gEmuBlockIoComponentName2.SupportedLanguages,
+ &Private->ControllerNameTable,
+ EmuIoThunk->ConfigString,
+ FALSE
+ );
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiBlockIoProtocolGuid, &Private->BlockIo,
+ &gEfiBlockIo2ProtocolGuid, &Private->BlockIo2,
+ NULL
+ );
+
+Done:
+ if (EFI_ERROR (Status)) {
+ if (Private != NULL) {
+ if (Private->ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+ }
+
+ gBS->FreePool (Private);
+
+ }
+
+ gBS->CloseProtocol (
+ Handle,
+ &gEmuIoThunkProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+ }
+
+ return Status;
+}
+
+
+/**
+ Stops a device controller or a bus controller.
+
+ The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
+ As a result, much of the error checking on the parameters to Stop() has been moved
+ into this common boot service. It is legal to call Stop() from other locations,
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
+ same driver's Start() function.
+ 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
+ EFI_HANDLE. In addition, all of these handles must have been created in this driver's
+ Start() function, and the Start() function must have called OpenProtocol() on
+ ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must
+ support a bus specific I/O protocol for the driver
+ to use to stop the device.
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
+ if NumberOfChildren is 0.
+
+ @retval EFI_SUCCESS The device was stopped.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuBlockIoDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status;
+ EMU_BLOCK_IO_PRIVATE *Private;
+
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiBlockIoProtocolGuid,
+ (void *)&BlockIo,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (BlockIo);
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Private->EfiHandle,
+ &gEfiBlockIoProtocolGuid, &Private->BlockIo,
+ &gEfiBlockIo2ProtocolGuid, &Private->BlockIo2,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->CloseProtocol (
+ Handle,
+ &gEmuIoThunkProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Destroy the IO interface.
+ //
+ Status = Private->IoThunk->Close (Private->IoThunk);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Free our instance data
+ //
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+ FreePool (Private);
+ }
+
+ return Status;
+}
+
+
+
+
+
+EFI_DRIVER_BINDING_PROTOCOL gEmuBlockIoDriverBinding = {
+ EmuBlockIoDriverBindingSupported,
+ EmuBlockIoDriverBindingStart,
+ EmuBlockIoDriverBindingStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+
+
+
+/**
+ The user Entry Point for module EmuBlockIo . 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
+InitializeEmuBlockIo (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EfiLibInstallAllDriverProtocols2 (
+ ImageHandle,
+ SystemTable,
+ &gEmuBlockIoDriverBinding,
+ ImageHandle,
+ &gEmuBlockIoComponentName,
+ &gEmuBlockIoComponentName2,
+ NULL,
+ NULL,
+ &gEmuBlockIoDriverDiagnostics,
+ &gEmuBlockIoDriverDiagnostics2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ return Status;
+}
+
+
+
diff --git a/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/EmuBlockIo.h b/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/EmuBlockIo.h
new file mode 100644
index 00000000000..e880a39f932
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/EmuBlockIo.h
@@ -0,0 +1,78 @@
+/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+ EmuBlockIo.h
+
+Abstract:
+
+ Produce block IO abstractions for real devices on your PC using Posix APIs.
+ The configuration of what devices to mount or emulate comes from UNIX
+ environment variables. The variables must be visible to the Microsoft*
+ Developer Studio for them to work.
+
+ * Other names and brands may be claimed as the property of others.
+
+**/
+
+#ifndef _EMU_BLOCK_IO_H_
+#define _EMU_BLOCK_IO_H_
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+//
+// Language supported for driverconfiguration protocol
+//
+
+#define EMU_BLOCK_IO_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'M', 'b', 'k')
+typedef struct {
+ UINTN Signature;
+ EMU_IO_THUNK_PROTOCOL *IoThunk;
+ EMU_BLOCK_IO_PROTOCOL *Io;
+
+ EFI_HANDLE EfiHandle;
+ EFI_BLOCK_IO_PROTOCOL BlockIo;
+ EFI_BLOCK_IO2_PROTOCOL BlockIo2;
+ EFI_BLOCK_IO_MEDIA Media;
+
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+
+} EMU_BLOCK_IO_PRIVATE;
+
+#define EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS(a) \
+ CR(a, EMU_BLOCK_IO_PRIVATE, BlockIo, EMU_BLOCK_IO_PRIVATE_SIGNATURE)
+
+#define EMU_BLOCK_IO2_PRIVATE_DATA_FROM_THIS(a) \
+ CR(a, EMU_BLOCK_IO_PRIVATE, BlockIo2, EMU_BLOCK_IO_PRIVATE_SIGNATURE)
+
+
+//
+// Block I/O Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gEmuBlockIoDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gEmuBlockIoComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gEmuBlockIoComponentName2;
+extern EFI_DRIVER_CONFIGURATION_PROTOCOL gEmuBlockIoDriverConfiguration;
+extern EFI_DRIVER_DIAGNOSTICS_PROTOCOL gEmuBlockIoDriverDiagnostics;
+extern EFI_DRIVER_DIAGNOSTICS2_PROTOCOL gEmuBlockIoDriverDiagnostics2;
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf b/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf
new file mode 100644
index 00000000000..b2392bb3a9f
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf
@@ -0,0 +1,64 @@
+## @file
+# Block Io driver
+#
+# Produce block IO abstractions for real devices on your PC using Unix APIs.
+# The configuration of what devices to mount or emulate comes from
+# environment variables.
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EmuBlockIo
+ FILE_GUID = C6760651-A38D-5F4F-AEAF-F6661549DF75
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeEmuBlockIo
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+# DRIVER_BINDING = gUnixBlockIoDriverBinding
+# COMPONENT_NAME = gUnixBlockIoComponentName
+# DRIVER_DIAG = gUnixBlockIoDriverDiagnostics
+#
+
+[Sources]
+ DriverDiagnostics.c
+ DriverConfiguration.c
+ ComponentName.c
+ EmuBlockIo.c
+ EmuBlockIo.h
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ UefiLib
+ UefiDriverEntryPoint
+ BaseLib
+ DebugLib
+
+
+[Guids]
+ gEmuPhysicalDisksGuid # SOMETIMES_CONSUMED
+ gEmuVirtualDisksGuid # ALWAYS_CONSUMED
+
+
+[Protocols]
+ gEfiBlockIoProtocolGuid # PROTOCOL BY_START
+ gEfiBlockIo2ProtocolGuid # PROTOCOL BY_START
+ gEmuIoThunkProtocolGuid # PROTOCOL TO_START
+ gEmuBlockIoProtocolGuid # PROTOCOL BY_START
diff --git a/CdeEmuPkg/EmulatorPkg/EmuBusDriverDxe/ComponentName.c b/CdeEmuPkg/EmulatorPkg/EmuBusDriverDxe/ComponentName.c
new file mode 100644
index 00000000000..ef847fae11d
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuBusDriverDxe/ComponentName.c
@@ -0,0 +1,244 @@
+/** @file
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "EmuBusDriverDxe.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+EmuBusDriverComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+EmuBusDriverComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gEmuBusDriverComponentName = {
+ EmuBusDriverComponentNameGetDriverName,
+ EmuBusDriverComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gEmuBusDriverComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) EmuBusDriverComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) EmuBusDriverComponentNameGetControllerName,
+ "en"
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mEmuBusDriverNameTable[] = {
+ { "eng", L"Emu Bus Driver" },
+ { 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
+EmuBusDriverComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mEmuBusDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gEmuBusDriverComponentName)
+ );
+}
+
+/**
+ 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
+EmuBusDriverComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+ EMU_IO_THUNK_PROTOCOL *EmuIo;
+ EMU_IO_DEVICE *Private;
+
+ //
+ // Make sure this driver is currently managing ControllHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ gEmuBusDriverBinding.DriverBindingHandle,
+ &gEmuThunkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // This is a bus driver, so ChildHandle can not be NULL.
+ //
+ if (ChildHandle == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = EfiTestChildHandle (
+ ControllerHandle,
+ ChildHandle,
+ &gEmuThunkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID**)&EmuIo,
+ gEmuBusDriverBinding.DriverBindingHandle,
+ ChildHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = EMU_IO_DEVICE_FROM_THIS (EmuIo);
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ Private->ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gEmuBusDriverComponentName)
+ );
+}
diff --git a/CdeEmuPkg/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.c b/CdeEmuPkg/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.c
new file mode 100644
index 00000000000..9fd964f054b
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.c
@@ -0,0 +1,528 @@
+/** @file
+ Emu Bus driver
+
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "EmuBusDriverDxe.h"
+
+
+
+//
+// DriverBinding protocol global
+//
+EFI_DRIVER_BINDING_PROTOCOL gEmuBusDriverBinding = {
+ EmuBusDriverBindingSupported,
+ EmuBusDriverBindingStart,
+ EmuBusDriverBindingStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+
+
+EFI_STATUS
+EFIAPI
+EmuBusDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EMU_THUNK_PROTOCOL *EmuThunk;
+
+ //
+ // Check the contents of the first Device Path Node of RemainingDevicePath to make sure
+ // it is a legal Device Path Node for this bus driver's children.
+ //
+ if (RemainingDevicePath != NULL) {
+ //
+ // Check if RemainingDevicePath is the End of Device Path Node,
+ // if yes, go on checking other conditions
+ //
+ if (!IsDevicePathEnd (RemainingDevicePath)) {
+ //
+ // If RemainingDevicePath isn't the End of Device Path Node,
+ // check its validation
+ //
+ if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||
+ RemainingDevicePath->SubType != HW_VENDOR_DP ||
+ DevicePathNodeLength(RemainingDevicePath) != sizeof(EMU_VENDOR_DEVICE_PATH_NODE)) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ }
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ (VOID **)&EmuThunk ,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ //
+ // Open the EFI Device Path protocol needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **)&ParentDevicePath,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+
+ //
+ // Close protocol, don't use device path protocol in the Support() function
+ //
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+EmuBusDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS InstallStatus;
+ EMU_THUNK_PROTOCOL *EmuThunk;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EMU_IO_DEVICE *EmuDevice;
+ EMU_BUS_DEVICE *EmuBusDevice;
+ EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
+ UINT16 ComponentName[512];
+ EMU_VENDOR_DEVICE_PATH_NODE *Node;
+ BOOLEAN CreateDevice;
+
+ InstallStatus = EFI_UNSUPPORTED;
+ Status = EFI_UNSUPPORTED;
+
+ //
+ // Grab the protocols we need
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **)&ParentDevicePath,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ return Status;
+ }
+
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ (VOID **)&EmuThunk,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
+ return Status;
+ }
+
+ if (Status != EFI_ALREADY_STARTED) {
+ EmuBusDevice = AllocatePool (sizeof (EMU_BUS_DEVICE));
+ if (EmuBusDevice == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ EmuBusDevice->Signature = EMU_BUS_DEVICE_SIGNATURE;
+ EmuBusDevice->ControllerNameTable = NULL;
+
+ AddUnicodeString2 (
+ "eng",
+ gEmuBusDriverComponentName.SupportedLanguages,
+ &EmuBusDevice->ControllerNameTable,
+ L"Emulator Bus Controller",
+ TRUE
+ );
+ AddUnicodeString2 (
+ "en",
+ gEmuBusDriverComponentName2.SupportedLanguages,
+ &EmuBusDevice->ControllerNameTable,
+ L"Emulator Bus Controller",
+ FALSE
+ );
+
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ControllerHandle,
+ &gEfiCallerIdGuid, EmuBusDevice,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable);
+ gBS->FreePool (EmuBusDevice);
+ return Status;
+ }
+ }
+
+
+ for (Status = EFI_SUCCESS, EmuIoThunk = NULL; !EFI_ERROR (Status); ) {
+ Status = EmuThunk->GetNextProtocol (TRUE, &EmuIoThunk);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ CreateDevice = TRUE;
+ if (RemainingDevicePath != NULL) {
+ CreateDevice = FALSE;
+ //
+ // Check if RemainingDevicePath is the End of Device Path Node,
+ // if yes, don't create any child device
+ //
+ if (!IsDevicePathEnd (RemainingDevicePath)) {
+ //
+ // If RemainingDevicePath isn't the End of Device Path Node,
+ // check its validation
+ //
+ Node = (EMU_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;
+ if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&
+ Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&
+ DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (EMU_VENDOR_DEVICE_PATH_NODE)
+ ) {
+ if (CompareGuid (&Node->VendorDevicePath.Guid, EmuIoThunk->Protocol) && Node->Instance == EmuIoThunk->Instance) {
+ CreateDevice = TRUE;
+ }
+ }
+ }
+ }
+
+ if (CreateDevice) {
+ //
+ // Allocate instance structure, and fill in parent information.
+ //
+ EmuDevice = AllocatePool (sizeof (EMU_IO_DEVICE));
+ if (EmuDevice == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ EmuDevice->Handle = NULL;
+ EmuDevice->ControllerHandle = ControllerHandle;
+ EmuDevice->ParentDevicePath = ParentDevicePath;
+ CopyMem (&EmuDevice->EmuIoThunk, EmuIoThunk, sizeof (EMU_IO_THUNK_PROTOCOL));
+
+ EmuDevice->ControllerNameTable = NULL;
+
+ StrnCpyS (
+ ComponentName,
+ sizeof (ComponentName) / sizeof (CHAR16),
+ EmuIoThunk->ConfigString,
+ sizeof (ComponentName) / sizeof (CHAR16)
+ );
+
+ EmuDevice->DevicePath = EmuBusCreateDevicePath (
+ ParentDevicePath,
+ EmuIoThunk->Protocol,
+ EmuIoThunk->Instance
+ );
+ if (EmuDevice->DevicePath == NULL) {
+ gBS->FreePool (EmuDevice);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ AddUnicodeString (
+ "eng",
+ gEmuBusDriverComponentName.SupportedLanguages,
+ &EmuDevice->ControllerNameTable,
+ ComponentName
+ );
+
+ EmuDevice->Signature = EMU_IO_DEVICE_SIGNATURE;
+
+ InstallStatus = gBS->InstallMultipleProtocolInterfaces (
+ &EmuDevice->Handle,
+ &gEfiDevicePathProtocolGuid, EmuDevice->DevicePath,
+ &gEmuIoThunkProtocolGuid, &EmuDevice->EmuIoThunk,
+ NULL
+ );
+ if (EFI_ERROR (InstallStatus)) {
+ FreeUnicodeStringTable (EmuDevice->ControllerNameTable);
+ gBS->FreePool (EmuDevice);
+ } else {
+ //
+ // Open For Child Device
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ (VOID **)&EmuThunk ,
+ This->DriverBindingHandle,
+ EmuDevice->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (!EFI_ERROR (Status)) {
+ InstallStatus = EFI_SUCCESS;
+ }
+ }
+ }
+ }
+
+ return InstallStatus;
+}
+
+
+EFI_STATUS
+EFIAPI
+EmuBusDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ BOOLEAN AllChildrenStopped;
+ EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
+ EMU_BUS_DEVICE *EmuBusDevice;
+ EMU_IO_DEVICE *EmuDevice;
+ EMU_THUNK_PROTOCOL *EmuThunk;
+
+ //
+ // Complete all outstanding transactions to Controller.
+ // Don't allow any new transaction to Controller to be started.
+ //
+
+ if (NumberOfChildren == 0) {
+ //
+ // Close the bus driver
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiCallerIdGuid,
+ (VOID **)&EmuBusDevice,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->UninstallMultipleProtocolInterfaces (
+ ControllerHandle,
+ &gEfiCallerIdGuid, EmuBusDevice,
+ NULL
+ );
+
+ FreeUnicodeStringTable (EmuBusDevice->ControllerNameTable);
+
+ gBS->FreePool (EmuBusDevice);
+
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+ return EFI_SUCCESS;
+ }
+
+ AllChildrenStopped = TRUE;
+
+ for (Index = 0; Index < NumberOfChildren; Index++) {
+
+ Status = gBS->OpenProtocol (
+ ChildHandleBuffer[Index],
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&EmuIoThunk,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ EmuDevice = EMU_IO_DEVICE_FROM_THIS (EmuIoThunk);
+
+ Status = gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ This->DriverBindingHandle,
+ EmuDevice->Handle
+ );
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ EmuDevice->Handle,
+ &gEfiDevicePathProtocolGuid, EmuDevice->DevicePath,
+ &gEmuIoThunkProtocolGuid, &EmuDevice->EmuIoThunk,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuThunkProtocolGuid,
+ (VOID **) &EmuThunk ,
+ This->DriverBindingHandle,
+ EmuDevice->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ } else {
+ //
+ // Close the child handle
+ //
+ FreeUnicodeStringTable (EmuDevice->ControllerNameTable);
+ FreePool (EmuDevice);
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ }
+ }
+
+ if (!AllChildrenStopped) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/*++
+
+Routine Description:
+ Create a device path node using Guid and InstanceNumber and append it to
+ the passed in RootDevicePath
+
+Arguments:
+ RootDevicePath - Root of the device path to return.
+
+ Guid - GUID to use in vendor device path node.
+
+ InstanceNumber - Instance number to use in the vendor device path. This
+ argument is needed to make sure each device path is unique.
+
+Returns:
+
+ EFI_DEVICE_PATH_PROTOCOL
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EmuBusCreateDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath,
+ IN EFI_GUID *Guid,
+ IN UINT16 InstanceNumber
+ )
+{
+ EMU_VENDOR_DEVICE_PATH_NODE DevicePath;
+
+ DevicePath.VendorDevicePath.Header.Type = HARDWARE_DEVICE_PATH;
+ DevicePath.VendorDevicePath.Header.SubType = HW_VENDOR_DP;
+ SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (EMU_VENDOR_DEVICE_PATH_NODE));
+
+ //
+ // The GUID defines the Class
+ //
+ CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID));
+
+ //
+ // Add an instance number so we can make sure there are no Device Path
+ // duplication.
+ //
+ DevicePath.Instance = InstanceNumber;
+
+ return AppendDevicePathNode (
+ RootDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath
+ );
+}
+
+
+
+/**
+ The user Entry Point for module EmuBusDriver. 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
+InitializeEmuBusDriver (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EfiLibInstallAllDriverProtocols (
+ ImageHandle,
+ SystemTable,
+ &gEmuBusDriverBinding,
+ ImageHandle,
+ &gEmuBusDriverComponentName,
+ NULL,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ return Status;
+}
+
+
+
+
diff --git a/CdeEmuPkg/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.h b/CdeEmuPkg/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.h
new file mode 100644
index 00000000000..71f1692caee
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.h
@@ -0,0 +1,110 @@
+/*++ @file
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EMU_BUS_DRIVER_H__
+#define __EMU_BUS_DRIVER_H__
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+extern EFI_DRIVER_BINDING_PROTOCOL gEmuBusDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gEmuBusDriverComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gEmuBusDriverComponentName2;
+
+
+//
+// Unix Bus Controller Structure
+//
+#define EMU_BUS_DEVICE_SIGNATURE SIGNATURE_32 ('L', 'X', 'B', 'D')
+
+typedef struct {
+ UINT64 Signature;
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+} EMU_BUS_DEVICE;
+
+//
+// Unix Child Device Controller Structure
+//
+#define EMU_IO_DEVICE_SIGNATURE SIGNATURE_32 ('L', 'X', 'V', 'D')
+
+typedef struct {
+ UINT64 Signature;
+ EFI_HANDLE Handle;
+ EMU_IO_THUNK_PROTOCOL EmuIoThunk;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ //
+ // Private data about the parent
+ //
+ EFI_HANDLE ControllerHandle;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+
+} EMU_IO_DEVICE;
+
+#define EMU_IO_DEVICE_FROM_THIS(a) \
+ CR(a, EMU_IO_DEVICE, EmuIoThunk, EMU_IO_DEVICE_SIGNATURE)
+
+
+
+//
+// Driver Binding Protocol function prototypes
+//
+EFI_STATUS
+EFIAPI
+EmuBusDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+
+EFI_STATUS
+EFIAPI
+EmuBusDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ParentHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+
+EFI_STATUS
+EFIAPI
+EmuBusDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+//
+// Unix Bus Driver private worker functions
+//
+EFI_DEVICE_PATH_PROTOCOL *
+EmuBusCreateDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath,
+ IN EFI_GUID *Guid,
+ IN UINT16 InstanceNumber
+ );
+
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf b/CdeEmuPkg/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf
new file mode 100644
index 00000000000..3453e71be7b
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf
@@ -0,0 +1,58 @@
+## @file
+# Emu Bus driver
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EmuBusDriver
+ FILE_GUID = 9842073D-95D9-9F49-BD3F-2E29525125DF
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeEmuBusDriver
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+# DRIVER_BINDING = gEmuBusDriverBinding
+# COMPONENT_NAME = gEmuBusDriverComponentName
+#
+
+[Sources]
+ ComponentName.c
+ EmuBusDriverDxe.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+
+[LibraryClasses]
+ DevicePathLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ PcdLib
+ UefiLib
+ UefiDriverEntryPoint
+ BaseLib
+ DebugLib
+
+
+[Protocols]
+ gEfiDevicePathProtocolGuid # PROTOCOL TO_START
+ gEmuThunkProtocolGuid # PROTOCOL TO_START
+ gEmuIoThunkProtocolGuid # PROTOCOL BY_START
+
+
+
diff --git a/CdeEmuPkg/EmulatorPkg/EmuGopDxe/ComponentName.c b/CdeEmuPkg/EmulatorPkg/EmuGopDxe/ComponentName.c
new file mode 100644
index 00000000000..fca86559fcf
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuGopDxe/ComponentName.c
@@ -0,0 +1,244 @@
+/** @file
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010,Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+**/
+
+#include "Gop.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+EmuGopComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+EmuGopComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+//
+// EFI Component Name Protocol
+//
+EFI_COMPONENT_NAME_PROTOCOL gEmuGopComponentName = {
+ EmuGopComponentNameGetDriverName,
+ EmuGopComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gEmuGopComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) EmuGopComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) EmuGopComponentNameGetControllerName,
+ "en"
+};
+
+
+EFI_UNICODE_STRING_TABLE mEmuGopDriverNameTable[] = {
+ { "eng", L"Emulator GOP Driver" },
+ { 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
+EmuGopComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mEmuGopDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gEmuGopComponentName)
+ );
+}
+
+
+/**
+ 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
+EmuGopComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ GOP_PRIVATE_DATA *Private;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver is currently managing ControllerHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ gEmuGopDriverBinding.DriverBindingHandle,
+ &gEmuIoThunkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID **)&GraphicsOutput,
+ gEmuGopDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = GOP_PRIVATE_DATA_FROM_THIS (GraphicsOutput);
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ Private->ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gEmuGopComponentName)
+ );
+}
diff --git a/CdeEmuPkg/EmulatorPkg/EmuGopDxe/EmuGopDxe.inf b/CdeEmuPkg/EmulatorPkg/EmuGopDxe/EmuGopDxe.inf
new file mode 100644
index 00000000000..8df7656d931
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuGopDxe/EmuGopDxe.inf
@@ -0,0 +1,64 @@
+## @file
+# GOP driver
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EmuGopDxe
+ FILE_GUID = BCC87E0D-86D6-4D4D-8040-2D983D368BD1
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeEmuGop
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+# DRIVER_BINDING = gEmuGopDriverBinding
+# COMPONENT_NAME = gEmuGopComponentName
+#
+
+[Sources]
+ ComponentName.c
+ GopScreen.c
+ GopDriver.c
+ GopInput.c
+ Gop.h
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ UefiLib
+ UefiDriverEntryPoint
+ BaseLib
+ DebugLib
+ KeyMapLib
+
+
+[Guids]
+ gEfiEventExitBootServicesGuid # SOMETIMES_CONSUMED Create Event: EVENT_GROUP_GUID
+
+
+[Protocols]
+ gEfiGraphicsOutputProtocolGuid
+ gEfiSimpleTextInProtocolGuid # PROTOCOL BY_START
+ gEfiSimpleTextInputExProtocolGuid # PROTOCOL BY_START
+ gEfiSimplePointerProtocolGuid # PROTOCOL BY_START
+ gEmuIoThunkProtocolGuid # PROTOCOL TO_START
+ gEmuGraphicsWindowProtocolGuid # PROTOCOL TO_START
diff --git a/CdeEmuPkg/EmulatorPkg/EmuGopDxe/Gop.h b/CdeEmuPkg/EmulatorPkg/EmuGopDxe/Gop.h
new file mode 100644
index 00000000000..aed44e368fc
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuGopDxe/Gop.h
@@ -0,0 +1,189 @@
+/*++ @file
+
+Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010,Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __UGA_H_
+#define __UGA_H_
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#define MAX_Q 256
+
+typedef struct {
+ UINTN Front;
+ UINTN Rear;
+ UINTN Count;
+ EFI_INPUT_KEY Q[MAX_Q];
+} GOP_QUEUE_FIXED;
+
+#define EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('U', 'g', 'S', 'n')
+typedef struct _EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY {
+ UINTN Signature;
+ EFI_HANDLE NotifyHandle;
+ EFI_KEY_DATA KeyData;
+ EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;
+ EFI_EVENT Event;
+ LIST_ENTRY NotifyEntry;
+} EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY;
+
+#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff
+
+typedef struct {
+ UINT32 HorizontalResolution;
+ UINT32 VerticalResolution;
+ UINT32 ColorDepth;
+ UINT32 RefreshRate;
+} GOP_MODE_DATA;
+
+
+
+extern EFI_DRIVER_BINDING_PROTOCOL gEmuGopDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gEmuGopComponentName;
+
+#define EMU_UGA_CLASS_NAME L"EmuGopWindow"
+
+#define GOP_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('G', 'o', 'p', 'N')
+typedef struct {
+ UINT64 Signature;
+
+ EFI_HANDLE Handle;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput;
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleTextIn;
+ EFI_SIMPLE_POINTER_PROTOCOL SimplePointer;
+
+ EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
+ EMU_GRAPHICS_WINDOW_PROTOCOL *EmuGraphicsWindow;
+
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+
+ EFI_SIMPLE_POINTER_MODE PointerMode;
+ //
+ // GOP Private Data for QueryMode ()
+ //
+ GOP_MODE_DATA *ModeData;
+
+
+ //
+ // UGA Private Data knowing when to start hardware
+ //
+ BOOLEAN HardwareNeedsStarting;
+
+ CHAR16 *WindowName;
+
+ GOP_QUEUE_FIXED Queue;
+
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleTextInEx;
+ EFI_KEY_STATE KeyState;
+ LIST_ENTRY NotifyList;
+} GOP_PRIVATE_DATA;
+
+
+#define GOP_PRIVATE_DATA_FROM_THIS(a) \
+ CR(a, GOP_PRIVATE_DATA, GraphicsOutput, GOP_PRIVATE_DATA_SIGNATURE)
+
+#define GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS(a) \
+ CR(a, GOP_PRIVATE_DATA, SimpleTextIn, GOP_PRIVATE_DATA_SIGNATURE)
+
+#define GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS(a) \
+ CR(a, GOP_PRIVATE_DATA, SimpleTextInEx, GOP_PRIVATE_DATA_SIGNATURE)
+
+#define GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS(a) \
+ CR(a, GOP_PRIVATE_DATA, SimplePointer, GOP_PRIVATE_DATA_SIGNATURE)
+
+
+//
+// Global Protocol Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gEmuGopDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gEmuGopComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gEmuGopComponentName2;
+
+//
+// Gop Hardware abstraction internal worker functions
+//
+EFI_STATUS
+EmuGopSupported (
+ IN EMU_IO_THUNK_PROTOCOL *EmuIoThunk
+ );
+
+EFI_STATUS
+EmuGopConstructor (
+ IN GOP_PRIVATE_DATA *Private
+ );
+
+EFI_STATUS
+EmuGopDestructor (
+ IN GOP_PRIVATE_DATA *Private
+ );
+
+
+EFI_STATUS
+GopPrivateAddQ (
+ IN GOP_PRIVATE_DATA *Private,
+ IN EFI_INPUT_KEY Key
+ );
+
+EFI_STATUS
+EmuGopInitializeSimpleTextInForWindow (
+ IN GOP_PRIVATE_DATA *Private
+ );
+
+EFI_STATUS
+EmuGopInitializeSimplePointerForWindow (
+ IN GOP_PRIVATE_DATA *Private
+ );
+
+EFI_STATUS
+EmuGopStartWindow (
+ IN GOP_PRIVATE_DATA *Private,
+ IN UINT32 HorizontalResolution,
+ IN UINT32 VerticalResolution,
+ IN UINT32 ColorDepth,
+ IN UINT32 RefreshRate
+ );
+
+VOID
+EFIAPI
+ShutdownGopEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+VOID
+EFIAPI
+GopPrivateMakeCallbackFunction (
+ IN VOID *Context,
+ IN EFI_KEY_DATA *KeyData
+ );
+
+VOID
+EFIAPI
+GopPrivateBreakCallbackFunction (
+ IN VOID *Context,
+ IN EFI_KEY_DATA *KeyData
+ );
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/EmuGopDxe/GopDriver.c b/CdeEmuPkg/EmulatorPkg/EmuGopDxe/GopDriver.c
new file mode 100644
index 00000000000..450e652899c
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuGopDxe/GopDriver.c
@@ -0,0 +1,437 @@
+/*++ @file
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010,Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "Gop.h"
+
+
+EFI_STATUS
+FreeNotifyList (
+ IN OUT LIST_ENTRY *ListHead
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ ListHead - The list head
+
+Returns:
+
+ EFI_SUCCESS - Free the notify list successfully
+ EFI_INVALID_PARAMETER - ListHead is invalid.
+
+**/
+{
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NotifyNode;
+
+ if (ListHead == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ while (!IsListEmpty (ListHead)) {
+ NotifyNode = CR (
+ ListHead->ForwardLink,
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
+ NotifyEntry,
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
+ );
+ RemoveEntryList (ListHead->ForwardLink);
+ gBS->FreePool (NotifyNode);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Tests to see if this driver supports a given controller. If a child device is provided,
+ it further tests to see if this driver supports creating a handle for the specified child device.
+
+ This function checks to see if the driver specified by This supports the device specified by
+ ControllerHandle. Drivers will typically use the device path attached to
+ ControllerHandle and/or the services from the bus I/O abstraction attached to
+ ControllerHandle to determine if the driver supports ControllerHandle. This function
+ may be called many times during platform initialization. In order to reduce boot times, the tests
+ performed by this function must be very small, and take as little time as possible to execute. This
+ function must not change the state of any hardware devices, and this function must be aware that the
+ device specified by ControllerHandle may already be managed by the same driver or a
+ different driver. This function must match its calls to AllocatePages() with FreePages(),
+ AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
+ Because ControllerHandle may have been previously started by the same driver, if a protocol is
+ already in the opened state, then it must not be closed with CloseProtocol(). This is required
+ to guarantee the state of ControllerHandle is not modified by this function.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to test. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For bus drivers, if this parameter is not NULL, then
+ the bus driver must determine if the bus controller specified
+ by ControllerHandle and the child controller specified
+ by RemainingDevicePath are both supported by this
+ bus driver.
+
+ @retval EFI_SUCCESS The device specified by ControllerHandle and
+ RemainingDevicePath is supported by the driver specified by This.
+ @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by the driver
+ specified by This.
+ @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by a different
+ driver or an application that requires exclusive access.
+ Currently not implemented.
+ @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
+ RemainingDevicePath is not supported by the driver specified by This.
+**/
+EFI_STATUS
+EFIAPI
+EmuGopDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&EmuIoThunk,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = EmuGopSupported (EmuIoThunk);
+
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ Handle,
+ &gEmuIoThunkProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ return Status;
+}
+
+
+/**
+ Starts a device controller or a bus controller.
+
+ The Start() function is designed to be invoked from the EFI boot service ConnectController().
+ As a result, much of the error checking on the parameters to Start() has been moved into this
+ common boot service. It is legal to call Start() from other locations,
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE.
+ 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
+ EFI_DEVICE_PATH_PROTOCOL.
+ 3. Prior to calling Start(), the Supported() function for the driver specified by This must
+ have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to start. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For a bus driver, if this parameter is NULL, then handles
+ for all the children of Controller are created by this driver.
+ If this parameter is not NULL and the first Device Path Node is
+ not the End of Device Path Node, then only the handle for the
+ child device specified by the first Device Path Node of
+ RemainingDevicePath is created by this driver.
+ If the first Device Path Node of RemainingDevicePath is
+ the End of Device Path Node, no child handle is created by this
+ driver.
+
+ @retval EFI_SUCCESS The device was started.
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval Others The driver failded to start the device.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
+ EFI_STATUS Status;
+ GOP_PRIVATE_DATA *Private;
+
+ //
+ // Grab the protocols we need
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&EmuIoThunk,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Allocate Private context data for SGO inteface.
+ //
+ Private = NULL;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (GOP_PRIVATE_DATA),
+ (VOID **)&Private
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ //
+ // Set up context record
+ //
+ Private->Signature = GOP_PRIVATE_DATA_SIGNATURE;
+ Private->Handle = Handle;
+ Private->EmuIoThunk = EmuIoThunk;
+ Private->WindowName = EmuIoThunk->ConfigString;
+ Private->ControllerNameTable = NULL;
+
+ AddUnicodeString (
+ "eng",
+ gEmuGopComponentName.SupportedLanguages,
+ &Private->ControllerNameTable,
+ EmuIoThunk->ConfigString
+ );
+ AddUnicodeString2 (
+ "en",
+ gEmuGopComponentName2.SupportedLanguages,
+ &Private->ControllerNameTable,
+ EmuIoThunk->ConfigString,
+ FALSE
+ );
+
+ Status = EmuGopConstructor (Private);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ //
+ // Publish the Gop interface to the world
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Private->Handle,
+ &gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput,
+ &gEfiSimpleTextInProtocolGuid, &Private->SimpleTextIn,
+ &gEfiSimplePointerProtocolGuid, &Private->SimplePointer,
+ &gEfiSimpleTextInputExProtocolGuid, &Private->SimpleTextInEx,
+ NULL
+ );
+
+Done:
+ if (EFI_ERROR (Status)) {
+
+ gBS->CloseProtocol (
+ Handle,
+ &gEmuIoThunkProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ if (Private != NULL) {
+ //
+ // On Error Free back private data
+ //
+ if (Private->ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+ }
+ if (Private->SimpleTextIn.WaitForKey != NULL) {
+ gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);
+ }
+ if (Private->SimpleTextInEx.WaitForKeyEx != NULL) {
+ gBS->CloseEvent (Private->SimpleTextInEx.WaitForKeyEx);
+ }
+ FreeNotifyList (&Private->NotifyList);
+
+ gBS->FreePool (Private);
+ }
+ }
+
+ return Status;
+}
+
+
+
+/**
+ Stops a device controller or a bus controller.
+
+ The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
+ As a result, much of the error checking on the parameters to Stop() has been moved
+ into this common boot service. It is legal to call Stop() from other locations,
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
+ same driver's Start() function.
+ 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
+ EFI_HANDLE. In addition, all of these handles must have been created in this driver's
+ Start() function, and the Start() function must have called OpenProtocol() on
+ ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must
+ support a bus specific I/O protocol for the driver
+ to use to stop the device.
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
+ if NumberOfChildren is 0.
+
+ @retval EFI_SUCCESS The device was stopped.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ EFI_STATUS Status;
+ GOP_PRIVATE_DATA *Private;
+
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID **)&GraphicsOutput,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // If the GOP interface does not exist the driver is not started
+ //
+ return EFI_NOT_STARTED;
+ }
+
+ //
+ // Get our private context information
+ //
+ Private = GOP_PRIVATE_DATA_FROM_THIS (GraphicsOutput);
+
+ //
+ // Remove the SGO interface from the system
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Private->Handle,
+ &gEfiGraphicsOutputProtocolGuid, &Private->GraphicsOutput,
+ &gEfiSimpleTextInProtocolGuid, &Private->SimpleTextIn,
+ &gEfiSimplePointerProtocolGuid, &Private->SimplePointer,
+ &gEfiSimpleTextInputExProtocolGuid, &Private->SimpleTextInEx,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Shutdown the hardware
+ //
+ Status = EmuGopDestructor (Private);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ gBS->CloseProtocol (
+ Handle,
+ &gEmuIoThunkProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ //
+ // Free our instance data
+ //
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+
+ Status = gBS->CloseEvent (Private->SimpleTextIn.WaitForKey);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->CloseEvent (Private->SimpleTextInEx.WaitForKeyEx);
+ ASSERT_EFI_ERROR (Status);
+
+ FreeNotifyList (&Private->NotifyList);
+
+ gBS->FreePool (Private);
+
+ }
+
+ return Status;
+}
+
+
+///
+/// This protocol provides the services required to determine if a driver supports a given controller.
+/// If a controller is supported, then it also provides routines to start and stop the controller.
+///
+EFI_DRIVER_BINDING_PROTOCOL gEmuGopDriverBinding = {
+ EmuGopDriverBindingSupported,
+ EmuGopDriverBindingStart,
+ EmuGopDriverBindingStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+
+
+/**
+ The user Entry Point for module EmuGop. 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
+InitializeEmuGop (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &gEmuGopDriverBinding,
+ ImageHandle,
+ &gEmuGopComponentName,
+ &gEmuGopComponentName2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ return Status;
+}
+
diff --git a/CdeEmuPkg/EmulatorPkg/EmuGopDxe/GopInput.c b/CdeEmuPkg/EmulatorPkg/EmuGopDxe/GopInput.c
new file mode 100644
index 00000000000..174817a9568
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuGopDxe/GopInput.c
@@ -0,0 +1,903 @@
+/*++ @file
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 0 2011,Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include "Gop.h"
+
+
+BOOLEAN
+GopPrivateIsKeyRegistered (
+ IN EFI_KEY_DATA *RegsiteredData,
+ IN EFI_KEY_DATA *InputData
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ RegsiteredData - A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was registered.
+ InputData - A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+Returns:
+ TRUE - Key be pressed matches a registered key.
+ FLASE - Match failed.
+
+**/
+{
+ ASSERT (RegsiteredData != NULL && InputData != NULL);
+
+ if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
+ (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {
+ return FALSE;
+ }
+
+ //
+ // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
+ //
+ if (RegsiteredData->KeyState.KeyShiftState != 0 &&
+ RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {
+ return FALSE;
+ }
+ if (RegsiteredData->KeyState.KeyToggleState != 0 &&
+ RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
+
+
+VOID
+EFIAPI
+GopPrivateMakeCallbackFunction (
+ IN VOID *Context,
+ IN EFI_KEY_DATA *KeyData
+ )
+{
+ LIST_ENTRY *Link;
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
+ GOP_PRIVATE_DATA *Private = (GOP_PRIVATE_DATA *)Context;
+
+ KeyMapMake (KeyData);
+
+ for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
+ CurrentNotify = CR (
+ Link,
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
+ NotifyEntry,
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
+ );
+ if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
+ // We could be called at a high TPL so signal an event to call the registered function
+ // at a lower TPL.
+ gBS->SignalEvent (CurrentNotify->Event);
+ }
+ }
+}
+
+
+VOID
+EFIAPI
+GopPrivateBreakCallbackFunction (
+ IN VOID *Context,
+ IN EFI_KEY_DATA *KeyData
+ )
+{
+ KeyMapBreak (KeyData);
+}
+
+
+
+//
+// Simple Text In implementation.
+//
+
+/**
+ Reset the input device and optionally run diagnostics
+
+ @param This Protocol instance pointer.
+ @param ExtendedVerification Driver may perform diagnostics on reset.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopSimpleTextInReset (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ GOP_PRIVATE_DATA *Private;
+ EFI_KEY_DATA KeyData;
+ EFI_TPL OldTpl;
+
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
+ if (Private->EmuGraphicsWindow == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ //
+ // A reset is draining the Queue
+ //
+ while (Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData) == EFI_SUCCESS)
+ ;
+
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existence of a keystroke via WaitForEvent () call.
+
+ @param This Protocol instance pointer.
+ @param Key A pointer to a buffer that is filled in with the keystroke
+ information for the key that was pressed.
+
+ @retval EFI_SUCCESS The keystroke information was returned.
+ @retval EFI_NOT_READY There was no keystroke data available.
+ @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
+ hardware errors.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopSimpleTextInReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ )
+{
+ GOP_PRIVATE_DATA *Private;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+ EFI_KEY_DATA KeyData;
+
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_THIS (This);
+ if (Private->EmuGraphicsWindow == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = Private->EmuGraphicsWindow->GetKey (Private->EmuGraphicsWindow, &KeyData);
+ if (!EFI_ERROR (Status)) {
+ if ((KeyData.Key.ScanCode == 0) && (KeyData.Key.UnicodeChar == 0)) {
+ // Modifier key was pressed
+ Status = EFI_NOT_READY;
+ } else {
+ CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
+ }
+ }
+
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+
+
+/**
+ SimpleTextIn and SimpleTextInEx Notify Wait Event
+
+ @param Event Event whose notification function is being invoked.
+ @param Context Pointer to GOP_PRIVATE_DATA.
+
+**/
+VOID
+EFIAPI
+EmuGopSimpleTextInWaitForKey (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ GOP_PRIVATE_DATA *Private;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ Private = (GOP_PRIVATE_DATA *) Context;
+ if (Private->EmuGraphicsWindow == NULL) {
+ return;
+ }
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = Private->EmuGraphicsWindow->CheckKey (Private->EmuGraphicsWindow);
+ if (!EFI_ERROR (Status)) {
+ //
+ // If a there is a key in the queue signal our event.
+ //
+ gBS->SignalEvent (Event);
+ }
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+}
+
+
+//
+// Simple Text Input Ex protocol functions
+//
+
+
+/**
+ The Reset() function resets the input device hardware. As part
+ of initialization process, the firmware/device will make a quick
+ but reasonable attempt to verify that the device is functioning.
+ If the ExtendedVerification flag is TRUE the firmware may take
+ an extended amount of time to verify the device is operating on
+ reset. Otherwise the reset operation is to occur as quickly as
+ possible. The hardware verification process is not defined by
+ this specification and is left up to the platform firmware or
+ driver to implement.
+
+ @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+ @param ExtendedVerification Indicates that the driver may
+ perform a more exhaustive
+ verification operation of the
+ device during reset.
+
+
+ @retval EFI_SUCCESS The device was reset.
+
+ @retval EFI_DEVICE_ERROR The device is not functioning
+ correctly and could not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopSimpleTextInExResetEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+ Routine Description:
+ Reset the input device and optionaly run diagnostics
+
+ Arguments:
+ This - Protocol instance pointer.
+ ExtendedVerification - Driver may perform diagnostics on reset.
+
+ Returns:
+ EFI_SUCCESS - The device was reset.
+
+**/
+{
+ return EFI_SUCCESS;
+}
+
+
+
+/**
+ The function reads the next keystroke from the input device. If
+ there is no pending keystroke the function returns
+ EFI_NOT_READY. If there is a pending keystroke, then
+ KeyData.Key.ScanCode is the EFI scan code defined in Error!
+ Reference source not found. The KeyData.Key.UnicodeChar is the
+ actual printable character or is zero if the key does not
+ represent a printable character (control key, function key,
+ etc.). The KeyData.KeyState is shift state for the character
+ reflected in KeyData.Key.UnicodeChar or KeyData.Key.ScanCode .
+ When interpreting the data from this function, it should be
+ noted that if a class of printable characters that are
+ normally adjusted by shift modifiers (e.g. Shift Key + "f"
+ key) would be presented solely as a KeyData.Key.UnicodeChar
+ without the associated shift state. So in the previous example
+ of a Shift Key + "f" key being pressed, the only pertinent
+ data returned would be KeyData.Key.UnicodeChar with the value
+ of "F". This of course would not typically be the case for
+ non-printable characters such as the pressing of the Right
+ Shift Key + F10 key since the corresponding returned data
+ would be reflected both in the KeyData.KeyState.KeyShiftState
+ and KeyData.Key.ScanCode values. UEFI drivers which implement
+ the EFI_SIMPLE_TEXT_INPUT_EX protocol are required to return
+ KeyData.Key and KeyData.KeyState values. These drivers must
+ always return the most current state of
+ KeyData.KeyState.KeyShiftState and
+ KeyData.KeyState.KeyToggleState. It should also be noted that
+ certain input devices may not be able to produce shift or toggle
+ state information, and in those cases the high order bit in the
+ respective Toggle and Shift state fields should not be active.
+
+
+ @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+ @param KeyData A pointer to a buffer that is filled in with
+ the keystroke state data for the key that was
+ pressed.
+
+
+ @retval EFI_SUCCESS The keystroke information was
+ returned.
+
+ @retval EFI_NOT_READY There was no keystroke data available.
+ EFI_DEVICE_ERROR The keystroke
+ information was not returned due to
+ hardware errors.
+
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopSimpleTextInExReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+ )
+/*++
+
+ Routine Description:
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existance of a keystroke via WaitForEvent () call.
+
+ Arguments:
+ This - Protocol instance pointer.
+ KeyData - A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+ Returns:
+ EFI_SUCCESS - The keystroke information was returned.
+ EFI_NOT_READY - There was no keystroke data availiable.
+ EFI_DEVICE_ERROR - The keystroke information was not returned due to
+ hardware errors.
+ EFI_INVALID_PARAMETER - KeyData is NULL.
+
+**/
+{
+ EFI_STATUS Status;
+ GOP_PRIVATE_DATA *Private;
+ EFI_TPL OldTpl;
+
+
+ if (KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
+ if (Private->EmuGraphicsWindow == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = Private->EmuGraphicsWindow->GetKey(Private->EmuGraphicsWindow, KeyData);
+
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+
+
+/**
+ The SetState() function allows the input device hardware to
+ have state settings adjusted.
+
+ @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+ @param KeyToggleState Pointer to the EFI_KEY_TOGGLE_STATE to
+ set the state for the input device.
+
+
+ @retval EFI_SUCCESS The device state was set appropriately.
+
+ @retval EFI_DEVICE_ERROR The device is not functioning
+ correctly and could not have the
+ setting adjusted.
+
+ @retval EFI_UNSUPPORTED The device does not support the
+ ability to have its state set.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopSimpleTextInExSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+ )
+{
+ GOP_PRIVATE_DATA *Private;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ if (KeyToggleState == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
+ if (Private->EmuGraphicsWindow == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ if (((Private->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||
+ ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = Private->EmuGraphicsWindow->KeySetState (Private->EmuGraphicsWindow, KeyToggleState);
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+
+/**
+ SimpleTextIn and SimpleTextInEx Notify Wait Event
+
+ @param Event Event whose notification function is being invoked.
+ @param Context Pointer to GOP_PRIVATE_DATA.
+
+**/
+VOID
+EFIAPI
+EmuGopRegisterKeyCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *ExNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *)Context;
+
+ ExNotify->KeyNotificationFn (&ExNotify->KeyData);
+}
+
+
+
+/**
+ The RegisterKeystrokeNotify() function registers a function
+ which will be called when a specified keystroke will occur.
+
+ @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+ @param KeyData A pointer to a buffer that is filled in with
+ the keystroke information for the key that was
+ pressed.
+
+ @param KeyNotificationFunction Points to the function to be
+ called when the key sequence
+ is typed specified by KeyData.
+
+
+ @param NotifyHandle Points to the unique handle assigned to
+ the registered notification.
+
+ @retval EFI_SUCCESS The device state was set
+ appropriately.
+
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary
+ data structures.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopSimpleTextInExRegisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT VOID **NotifyHandle
+ )
+{
+ EFI_STATUS Status;
+ GOP_PRIVATE_DATA *Private;
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
+ LIST_ENTRY *Link;
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify;
+
+ if (KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
+
+ //
+ // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
+ //
+ for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
+ CurrentNotify = CR (
+ Link,
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
+ NotifyEntry,
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
+ );
+ if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
+ if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
+ *NotifyHandle = CurrentNotify->NotifyHandle;
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ //
+ // Allocate resource to save the notification function
+ //
+ NewNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) AllocateZeroPool (sizeof (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY));
+ if (NewNotify == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewNotify->Signature = EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE;
+ NewNotify->KeyNotificationFn = KeyNotificationFunction;
+ NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify;
+ CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData));
+ InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry);
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ EmuGopRegisterKeyCallback,
+ NewNotify,
+ &NewNotify->Event
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ *NotifyHandle = NewNotify->NotifyHandle;
+
+ return EFI_SUCCESS;
+
+}
+
+
+/**
+ The UnregisterKeystrokeNotify() function removes the
+ notification which was previously registered.
+
+ @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.
+
+ @param NotificationHandle The handle of the notification
+ function being unregistered.
+
+ @retval EFI_SUCCESS The device state was set appropriately.
+
+ @retval EFI_INVALID_PARAMETER The NotificationHandle is
+ invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopSimpleTextInExUnregisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN VOID *NotificationHandle
+ )
+/*++
+
+ Routine Description:
+ Remove a registered notification function from a particular keystroke.
+
+ Arguments:
+ This - Protocol instance pointer.
+ NotificationHandle - The handle of the notification function being unregistered.
+
+ Returns:
+ EFI_SUCCESS - The notification function was unregistered successfully.
+ EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
+
+**/
+{
+ GOP_PRIVATE_DATA *Private;
+ LIST_ENTRY *Link;
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify;
+
+ if (NotificationHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) NotificationHandle)->Signature != EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This);
+
+ for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) {
+ CurrentNotify = CR (
+ Link,
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY,
+ NotifyEntry,
+ EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE
+ );
+ if (CurrentNotify->NotifyHandle == NotificationHandle) {
+ //
+ // Remove the notification function from NotifyList and free resources
+ //
+ RemoveEntryList (&CurrentNotify->NotifyEntry);
+
+ gBS->CloseEvent (CurrentNotify->Event);
+
+ gBS->FreePool (CurrentNotify);
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Can not find the specified Notification Handle
+ //
+ return EFI_INVALID_PARAMETER;
+}
+
+
+
+/**
+ Initialize SimplelTextIn and SimpleTextInEx protocols in the Private
+ context structure.
+
+ @param Private Context structure to fill in.
+
+ @return EFI_SUCCESS Initialization was a success
+
+**/
+EFI_STATUS
+EmuGopInitializeSimpleTextInForWindow (
+ IN GOP_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Initialize Simple Text In protoocol
+ //
+ Private->SimpleTextIn.Reset = EmuGopSimpleTextInReset;
+ Private->SimpleTextIn.ReadKeyStroke = EmuGopSimpleTextInReadKeyStroke;
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ EmuGopSimpleTextInWaitForKey,
+ Private,
+ &Private->SimpleTextIn.WaitForKey
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ //
+ // Initialize Simple Text In Ex
+ //
+
+ Private->SimpleTextInEx.Reset = EmuGopSimpleTextInExResetEx;
+ Private->SimpleTextInEx.ReadKeyStrokeEx = EmuGopSimpleTextInExReadKeyStrokeEx;
+ Private->SimpleTextInEx.SetState = EmuGopSimpleTextInExSetState;
+ Private->SimpleTextInEx.RegisterKeyNotify = EmuGopSimpleTextInExRegisterKeyNotify;
+ Private->SimpleTextInEx.UnregisterKeyNotify = EmuGopSimpleTextInExUnregisterKeyNotify;
+
+ Private->SimpleTextInEx.Reset (&Private->SimpleTextInEx, FALSE);
+
+ InitializeListHead (&Private->NotifyList);
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ EmuGopSimpleTextInWaitForKey,
+ Private,
+ &Private->SimpleTextInEx.WaitForKeyEx
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ return Status;
+}
+
+
+
+
+
+
+
+//
+// Simple Pointer implementation.
+//
+
+
+/**
+ Resets the pointer device hardware.
+
+ @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL
+ instance.
+ @param ExtendedVerification Indicates that the driver may perform a more exhaustive
+ verification operation of the device during reset.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopSimplePointerReset (
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ GOP_PRIVATE_DATA *Private;
+ EFI_SIMPLE_POINTER_STATE State;
+ EFI_TPL OldTpl;
+
+ Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This);
+ if (Private->EmuGraphicsWindow == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ //
+ // A reset is draining the Queue
+ //
+ while (Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, &State) == EFI_SUCCESS)
+ ;
+
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Retrieves the current state of a pointer device.
+
+ @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL
+ instance.
+ @param State A pointer to the state information on the pointer device.
+
+ @retval EFI_SUCCESS The state of the pointer device was returned in State.
+ @retval EFI_NOT_READY The state of the pointer device has not changed since the last call to
+ GetState().
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's
+ current state.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopSimplePointerGetState (
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN OUT EFI_SIMPLE_POINTER_STATE *State
+ )
+{
+ GOP_PRIVATE_DATA *Private;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ Private = GOP_PRIVATE_DATA_FROM_POINTER_MODE_THIS (This);
+ if (Private->EmuGraphicsWindow == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = Private->EmuGraphicsWindow->GetPointerState (Private->EmuGraphicsWindow, State);
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+
+/**
+ SimplePointer Notify Wait Event
+
+ @param Event Event whose notification function is being invoked.
+ @param Context Pointer to GOP_PRIVATE_DATA.
+
+**/
+VOID
+EFIAPI
+EmuGopSimplePointerWaitForInput (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ GOP_PRIVATE_DATA *Private;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ Private = (GOP_PRIVATE_DATA *) Context;
+ if (Private->EmuGraphicsWindow == NULL) {
+ return;
+ }
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Status = Private->EmuGraphicsWindow->CheckPointer (Private->EmuGraphicsWindow);
+ if (!EFI_ERROR (Status)) {
+ //
+ // If the pointer state has changed, signal our event.
+ //
+ gBS->SignalEvent (Event);
+ }
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+}
+
+
+/**
+ SimplePointer constructor
+
+ @param Private Context structure to fill in.
+
+ @retval EFI_SUCCESS Constructor had success
+
+**/
+EFI_STATUS
+EmuGopInitializeSimplePointerForWindow (
+ IN GOP_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Initialize Simple Pointer protoocol
+ //
+ Private->PointerMode.ResolutionX = 1;
+ Private->PointerMode.ResolutionY = 1;
+ Private->PointerMode.ResolutionZ = 1;
+ Private->PointerMode.LeftButton = TRUE;
+ Private->PointerMode.RightButton = TRUE;
+
+ Private->SimplePointer.Reset = EmuGopSimplePointerReset;
+ Private->SimplePointer.GetState = EmuGopSimplePointerGetState;
+ Private->SimplePointer.Mode = &Private->PointerMode;
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ EmuGopSimplePointerWaitForInput,
+ Private,
+ &Private->SimplePointer.WaitForInput
+ );
+
+ return Status;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/EmuGopDxe/GopScreen.c b/CdeEmuPkg/EmulatorPkg/EmuGopDxe/GopScreen.c
new file mode 100644
index 00000000000..7ddab6cb2a5
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuGopDxe/GopScreen.c
@@ -0,0 +1,410 @@
+/*++ @file
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+ EmuGopScreen.c
+
+Abstract:
+
+ This file produces the graphics abstration of UGA. It is called by
+ EmuGopDriver.c file which deals with the EFI 1.1 driver model.
+ This file just does graphics.
+
+**/
+
+#include "Gop.h"
+
+
+EFI_EVENT mGopScreenExitBootServicesEvent;
+
+GOP_MODE_DATA mGopModeData[] = {
+ { 800, 600, 0, 0 },
+ { 640, 480, 0, 0 },
+ { 720, 400, 0, 0 },
+ {1024, 768, 0, 0 },
+ {1280, 1024, 0, 0 }
+ };
+
+
+/**
+ Returns information for an available graphics mode that the graphics device
+ and the set of active video output devices supports.
+
+ @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
+ @param ModeNumber The mode number to return information on.
+ @param SizeOfInfo A pointer to the size, in bytes, of the Info buffer.
+ @param Info A pointer to callee allocated buffer that returns information about ModeNumber.
+
+ @retval EFI_SUCCESS Mode information returned.
+ @retval EFI_BUFFER_TOO_SMALL The Info buffer was too small.
+ @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode.
+ @retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
+ @retval EFI_INVALID_PARAMETER One of the input args was NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopQuerytMode (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber,
+ OUT UINTN *SizeOfInfo,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+ )
+{
+ GOP_PRIVATE_DATA *Private;
+
+ Private = GOP_PRIVATE_DATA_FROM_THIS (This);
+
+ if (Info == NULL || SizeOfInfo == NULL || (UINTN) 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);
+
+ (*Info)->Version = 0;
+ (*Info)->HorizontalResolution = Private->ModeData[ModeNumber].HorizontalResolution;
+ (*Info)->VerticalResolution = Private->ModeData[ModeNumber].VerticalResolution;
+ (*Info)->PixelFormat = PixelBltOnly;
+ (*Info)->PixelsPerScanLine = (*Info)->HorizontalResolution;
+
+ return EFI_SUCCESS;
+}
+
+
+
+/**
+ Set the video device into the specified mode and clears the visible portions of
+ the output display to black.
+
+ @param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
+ @param ModeNumber Abstraction that defines the current video mode.
+
+ @retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected.
+ @retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
+ @retval EFI_UNSUPPORTED ModeNumber is not supported by this device.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopSetMode (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber
+ )
+{
+ EFI_STATUS Status;
+ GOP_PRIVATE_DATA *Private;
+ GOP_MODE_DATA *ModeData;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Fill;
+
+ Private = GOP_PRIVATE_DATA_FROM_THIS (This);
+
+ if (ModeNumber >= This->Mode->MaxMode) {
+ return EFI_UNSUPPORTED;
+ }
+
+ ModeData = &Private->ModeData[ModeNumber];
+ This->Mode->Mode = ModeNumber;
+ Private->GraphicsOutput.Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
+ Private->GraphicsOutput.Mode->Info->VerticalResolution = ModeData->VerticalResolution;
+ Private->GraphicsOutput.Mode->Info->PixelsPerScanLine = ModeData->HorizontalResolution;
+
+ if (Private->HardwareNeedsStarting) {
+ Status = EmuGopStartWindow (
+ Private,
+ ModeData->HorizontalResolution,
+ ModeData->VerticalResolution,
+ ModeData->ColorDepth,
+ ModeData->RefreshRate
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Private->HardwareNeedsStarting = FALSE;
+ }
+
+
+ Status = Private->EmuGraphicsWindow->Size(
+ Private->EmuGraphicsWindow,
+ ModeData->HorizontalResolution,
+ ModeData->VerticalResolution
+ );
+
+
+ Fill.Red = 0;
+ Fill.Green = 0;
+ Fill.Blue = 0;
+ This->Blt (
+ This,
+ &Fill,
+ EfiBltVideoFill,
+ 0,
+ 0,
+ 0,
+ 0,
+ ModeData->HorizontalResolution,
+ ModeData->VerticalResolution,
+ ModeData->HorizontalResolution * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ );
+ return EFI_SUCCESS;
+}
+
+
+
+/**
+ Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer.
+
+ @param This Protocol instance pointer.
+ @param BltBuffer Buffer containing data to blit into video buffer. This
+ buffer has a size of Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)
+ @param BltOperation Operation to perform on BlitBuffer and video memory
+ @param SourceX X coordinate of source for the BltBuffer.
+ @param SourceY Y coordinate of source for the BltBuffer.
+ @param DestinationX X coordinate of destination for the BltBuffer.
+ @param DestinationY Y coordinate of destination for the BltBuffer.
+ @param Width Width of rectangle in BltBuffer in pixels.
+ @param Height Hight of rectangle in BltBuffer in pixels.
+ @param Delta OPTIONAL
+
+ @retval EFI_SUCCESS The Blt operation completed.
+ @retval EFI_INVALID_PARAMETER BltOperation is not valid.
+ @retval EFI_DEVICE_ERROR A hardware error occurred writting to the video buffer.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuGopBlt (
+ 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 OPTIONAL
+ )
+{
+ GOP_PRIVATE_DATA *Private;
+ EFI_TPL OriginalTPL;
+ EFI_STATUS Status;
+ EMU_GRAPHICS_WINDOWS__BLT_ARGS GopBltArgs;
+
+ Private = GOP_PRIVATE_DATA_FROM_THIS (This);
+
+ if ((UINT32)BltOperation >= EfiGraphicsOutputBltOperationMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width == 0 || Height == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // If Delta is zero, then the entire BltBuffer is being used, so Delta
+ // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
+ // the number of bytes in each row can be computed.
+ //
+ if (Delta == 0) {
+ Delta = Width * sizeof (EFI_UGA_PIXEL);
+ }
+
+ //
+ // 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);
+
+ //
+ // Pack UGA Draw protocol parameters to EMU_GRAPHICS_WINDOWS__BLT_ARGS structure to adapt to
+ // GopBlt() API of Unix UGA IO protocol.
+ //
+ GopBltArgs.DestinationX = DestinationX;
+ GopBltArgs.DestinationY = DestinationY;
+ GopBltArgs.Height = Height;
+ GopBltArgs.Width = Width;
+ GopBltArgs.SourceX = SourceX;
+ GopBltArgs.SourceY = SourceY;
+ GopBltArgs.Delta = Delta;
+ Status = Private->EmuGraphicsWindow->Blt (
+ Private->EmuGraphicsWindow,
+ (EFI_UGA_PIXEL *)BltBuffer,
+ (EFI_UGA_BLT_OPERATION)BltOperation,
+ &GopBltArgs
+ );
+
+ gBS->RestoreTPL (OriginalTPL);
+
+ return Status;
+}
+
+
+//
+// Construction and Destruction functions
+//
+
+EFI_STATUS
+EmuGopSupported (
+ IN EMU_IO_THUNK_PROTOCOL *EmuIoThunk
+ )
+{
+ //
+ // Check to see if the IO abstraction represents a device type we support.
+ //
+ // This would be replaced a check of PCI subsystem ID, etc.
+ //
+ if (!CompareGuid (EmuIoThunk->Protocol, &gEmuGraphicsWindowProtocolGuid)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EmuGopStartWindow (
+ IN GOP_PRIVATE_DATA *Private,
+ IN UINT32 HorizontalResolution,
+ IN UINT32 VerticalResolution,
+ IN UINT32 ColorDepth,
+ IN UINT32 RefreshRate
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Register to be notified on exit boot services so we can destroy the window.
+ //
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,
+ TPL_CALLBACK,
+ ShutdownGopEvent,
+ Private,
+ &mGopScreenExitBootServicesEvent
+ );
+
+ Status = Private->EmuIoThunk->Open (Private->EmuIoThunk);
+ if (!EFI_ERROR (Status)) {
+ Private->EmuGraphicsWindow = Private->EmuIoThunk->Interface;
+
+ // Register callback to support RegisterKeyNotify()
+ Status = Private->EmuGraphicsWindow->RegisterKeyNotify (
+ Private->EmuGraphicsWindow,
+ GopPrivateMakeCallbackFunction,
+ GopPrivateBreakCallbackFunction,
+ Private
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ return Status;
+}
+
+EFI_STATUS
+EmuGopConstructor (
+ GOP_PRIVATE_DATA *Private
+ )
+{
+ Private->ModeData = mGopModeData;
+
+ Private->GraphicsOutput.QueryMode = EmuGopQuerytMode;
+ Private->GraphicsOutput.SetMode = EmuGopSetMode;
+ Private->GraphicsOutput.Blt = EmuGopBlt;
+
+ //
+ // Allocate buffer for Graphics Output Protocol mode information
+ //
+ Private->GraphicsOutput.Mode = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE));
+ if (Private->GraphicsOutput.Mode == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ Private->GraphicsOutput.Mode->Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
+ if (Private->GraphicsOutput.Mode->Info == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Private->GraphicsOutput.Mode->MaxMode = sizeof(mGopModeData) / sizeof(GOP_MODE_DATA);
+ //
+ // Till now, we have no idea about the window size.
+ //
+ Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
+ Private->GraphicsOutput.Mode->Info->Version = 0;
+ Private->GraphicsOutput.Mode->Info->HorizontalResolution = 0;
+ Private->GraphicsOutput.Mode->Info->VerticalResolution = 0;
+ Private->GraphicsOutput.Mode->Info->PixelFormat = PixelBltOnly;
+ Private->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+ Private->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) (UINTN) NULL;
+ Private->GraphicsOutput.Mode->FrameBufferSize = 0;
+
+ Private->HardwareNeedsStarting = TRUE;
+ Private->EmuGraphicsWindow = NULL;
+
+ EmuGopInitializeSimpleTextInForWindow (Private);
+
+ EmuGopInitializeSimplePointerForWindow (Private);
+
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+EmuGopDestructor (
+ GOP_PRIVATE_DATA *Private
+ )
+{
+ if (!Private->HardwareNeedsStarting) {
+ Private->EmuIoThunk->Close (Private->EmuIoThunk);
+ Private->EmuGraphicsWindow = NULL;
+ }
+
+ //
+ // Free graphics output protocol occupied resource
+ //
+ if (Private->GraphicsOutput.Mode != NULL) {
+ if (Private->GraphicsOutput.Mode->Info != NULL) {
+ FreePool (Private->GraphicsOutput.Mode->Info);
+ }
+ FreePool (Private->GraphicsOutput.Mode);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+EFIAPI
+ShutdownGopEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ This is the UGA screen's callback notification function for exit-boot-services.
+ All we do here is call EmuGopDestructor().
+
+Arguments:
+
+ Event - not used
+ Context - pointer to the Private structure.
+
+Returns:
+
+ None.
+
+**/
+{
+ EmuGopDestructor (Context);
+}
+
diff --git a/CdeEmuPkg/EmulatorPkg/EmuSimpleFileSystemDxe/ComponentName.c b/CdeEmuPkg/EmulatorPkg/EmuSimpleFileSystemDxe/ComponentName.c
new file mode 100644
index 00000000000..7e3e78c6e18
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuSimpleFileSystemDxe/ComponentName.c
@@ -0,0 +1,238 @@
+/** @file
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "EmuSimpleFileSystem.h"
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gEmuSimpleFileSystemComponentName = {
+ EmuSimpleFileSystemComponentNameGetDriverName,
+ EmuSimpleFileSystemComponentNameGetControllerName,
+ "eng"
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gEmuSimpleFileSystemComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)EmuSimpleFileSystemComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)EmuSimpleFileSystemComponentNameGetControllerName,
+ "en"
+};
+
+EFI_UNICODE_STRING_TABLE mEmuSimpleFileSystemDriverNameTable[] = {
+ {
+ "eng;en",
+ L"Emu Simple File System Driver"
+ },
+ {
+ 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
+EmuSimpleFileSystemComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mEmuSimpleFileSystemDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gEmuSimpleFileSystemComponentName)
+ );
+}
+
+
+/**
+ 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
+EmuSimpleFileSystemComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
+ EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver is currently managing ControllerHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ gEmuSimpleFileSystemDriverBinding.DriverBindingHandle,
+ &gEmuIoThunkProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID**)&SimpleFileSystem,
+ gEmuSimpleFileSystemDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem);
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ Private->ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gEmuSimpleFileSystemComponentName)
+ );
+}
diff --git a/CdeEmuPkg/EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.c b/CdeEmuPkg/EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.c
new file mode 100644
index 00000000000..f2f1cb1438f
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.c
@@ -0,0 +1,938 @@
+/*++ @file
+ Produce Simple File System abstractions for directories on your PC using Posix APIs.
+ The configuration of what devices to mount or emulate comes from UNIX
+ environment variables. The variables must be visible to the Microsoft*
+ Developer Studio for them to work.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "EmuSimpleFileSystem.h"
+
+
+
+
+/**
+ Opens a new file relative to the source file's location.
+
+ @param This The protocol instance pointer.
+ @param NewHandle Returns File Handle for FileName.
+ @param FileName Null terminated string. "\", ".", and ".." are supported.
+ @param OpenMode Open mode for file.
+ @param Attributes Only used for EFI_FILE_MODE_CREATE.
+
+ @retval EFI_SUCCESS The device was opened.
+ @retval EFI_NOT_FOUND The specified file could not be found on the device.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_MEDIA_CHANGED The media has changed.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_ACCESS_DENIED The service denied access to the file.
+ @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
+ @retval EFI_VOLUME_FULL The volume is full.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemOpen (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ )
+{
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+ EMU_EFI_FILE_PRIVATE *PrivateFile;
+ EMU_EFI_FILE_PRIVATE *NewPrivateFile;
+
+ //
+ // Check for obvious invalid parameters.
+ //
+ if (This == NULL || NewHandle == NULL || FileName == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (OpenMode) {
+ case EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
+ if (Attributes &~EFI_FILE_VALID_ATTR) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Attributes & EFI_FILE_READ_ONLY) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // fall through
+ //
+ case EFI_FILE_MODE_READ:
+ case EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE:
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ NewPrivateFile = AllocateCopyPool (sizeof (EMU_EFI_FILE_PRIVATE), PrivateFile);
+ if (NewPrivateFile == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+
+ Status = PrivateFile->Io->Open (PrivateFile->Io, &NewPrivateFile->Io, FileName, OpenMode, Attributes);
+ if (!EFI_ERROR (Status)) {
+ *NewHandle = &NewPrivateFile->EfiFile;
+ } else {
+ *NewHandle = NULL;
+ FreePool (NewPrivateFile);
+ }
+
+Done:
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+
+
+/**
+ Close the file handle
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS The file was closed.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemClose (
+ IN EFI_FILE_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ EMU_EFI_FILE_PRIVATE *PrivateFile;
+ EFI_TPL OldTpl;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Status = PrivateFile->Io->Close (PrivateFile->Io);
+ if (!EFI_ERROR (Status)) {
+ gBS->FreePool (PrivateFile);
+ }
+
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+
+/**
+ Close and delete the file handle.
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS The file was closed and deleted.
+ @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemDelete (
+ IN EFI_FILE_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ EMU_EFI_FILE_PRIVATE *PrivateFile;
+ EFI_TPL OldTpl;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ Status = PrivateFile->Io->Delete (PrivateFile->Io);
+ if (!EFI_ERROR (Status)) {
+ gBS->FreePool (PrivateFile);
+ }
+
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+
+/**
+ Read data from the file.
+
+ @param This Protocol instance pointer.
+ @param BufferSize On input size of buffer, on output amount of data in buffer.
+ @param Buffer The buffer in which data is read.
+
+ @retval EFI_SUCCESS Data was read.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_BUFFER_TO_SMALL BufferSize is too small. BufferSize contains required size.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemRead (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ EMU_EFI_FILE_PRIVATE *PrivateFile;
+ EFI_TPL OldTpl;
+
+ if (This == NULL || BufferSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((*BufferSize != 0) && (Buffer == NULL)) {
+ // Buffer can be NULL if *BufferSize is zero
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ Status = PrivateFile->Io->Read (PrivateFile->Io, BufferSize, Buffer);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+/**
+ Write data to a file.
+
+ @param This Protocol instance pointer.
+ @param BufferSize On input size of buffer, on output amount of data in buffer.
+ @param Buffer The buffer in which data to write.
+
+ @retval EFI_SUCCESS Data was written.
+ @retval EFI_UNSUPPORTED Writes to Open directory are not supported.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The device is write protected.
+ @retval EFI_ACCESS_DENIED The file was open for read only.
+ @retval EFI_VOLUME_FULL The volume is full.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemWrite (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ EMU_EFI_FILE_PRIVATE *PrivateFile;
+ EFI_TPL OldTpl;
+
+ if (This == NULL || BufferSize == NULL || Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ Status = PrivateFile->Io->Write (PrivateFile->Io, BufferSize, Buffer);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+/**
+ Get a file's current position
+
+ @param This Protocol instance pointer.
+ @param Position Byte position from the start of the file.
+
+ @retval EFI_SUCCESS Position was updated.
+ @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemGetPosition (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT UINT64 *Position
+ )
+{
+ EFI_STATUS Status;
+ EMU_EFI_FILE_PRIVATE *PrivateFile;
+ EFI_TPL OldTpl;
+
+ if (This == NULL || Position == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ Status = PrivateFile->Io->GetPosition (PrivateFile->Io, Position);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+
+/**
+ Set file's current position
+
+ @param This Protocol instance pointer.
+ @param Position Byte position from the start of the file.
+
+ @retval EFI_SUCCESS Position was updated.
+ @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open..
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemSetPosition (
+ IN EFI_FILE_PROTOCOL *This,
+ IN UINT64 Position
+ )
+{
+ EFI_STATUS Status;
+ EMU_EFI_FILE_PRIVATE *PrivateFile;
+ EFI_TPL OldTpl;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ Status = PrivateFile->Io->SetPosition (PrivateFile->Io, Position);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+/**
+ Get information about a file.
+
+ @param This Protocol instance pointer.
+ @param InformationType Type of information to return in Buffer.
+ @param BufferSize On input size of buffer, on output amount of data in buffer.
+ @param Buffer The buffer to return data.
+
+ @retval EFI_SUCCESS Data was returned.
+ @retval EFI_UNSUPPORTED InformationType is not supported.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The device is write protected.
+ @retval EFI_ACCESS_DENIED The file was open for read only.
+ @retval EFI_BUFFER_TOO_SMALL Buffer was too small; required size returned in BufferSize.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemGetInfo (
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ EMU_EFI_FILE_PRIVATE *PrivateFile;
+ EFI_TPL OldTpl;
+
+ if (This == NULL || InformationType == NULL || BufferSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ Status = PrivateFile->Io->GetInfo (PrivateFile->Io, InformationType, BufferSize, Buffer);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+/**
+ Set information about a file
+
+ @param File Protocol instance pointer.
+ @param InformationType Type of information in Buffer.
+ @param BufferSize Size of buffer.
+ @param Buffer The data to write.
+
+ @retval EFI_SUCCESS Data was set.
+ @retval EFI_UNSUPPORTED InformationType is not supported.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The device is write protected.
+ @retval EFI_ACCESS_DENIED The file was open for read only.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemSetInfo (
+ IN EFI_FILE_PROTOCOL*This,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ EMU_EFI_FILE_PRIVATE *PrivateFile;
+ EFI_TPL OldTpl;
+
+ //
+ // Check for invalid parameters.
+ //
+ if (This == NULL || InformationType == NULL || BufferSize == 0 || Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ Status = PrivateFile->Io->SetInfo (PrivateFile->Io, InformationType, BufferSize, Buffer);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+/**
+ Flush data back for the file handle.
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS Data was flushed.
+ @retval EFI_UNSUPPORTED Writes to Open directory are not supported.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The device is write protected.
+ @retval EFI_ACCESS_DENIED The file was open for read only.
+ @retval EFI_VOLUME_FULL The volume is full.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemFlush (
+ IN EFI_FILE_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ EMU_EFI_FILE_PRIVATE *PrivateFile;
+ EFI_TPL OldTpl;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This);
+
+ Status = PrivateFile->Io->Flush (PrivateFile->Io);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+
+/**
+ Open the root directory on a volume.
+
+ @param This Protocol instance pointer.
+ @param Root Returns an Open file handle for the root directory
+
+ @retval EFI_SUCCESS The device was opened.
+ @retval EFI_UNSUPPORTED This volume does not support the file system.
+ @retval EFI_NO_MEDIA The device has no media.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_ACCESS_DENIED The service denied access to the file.
+ @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemOpenVolume (
+ IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **Root
+ )
+{
+ EFI_STATUS Status;
+ EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private;
+ EMU_EFI_FILE_PRIVATE *PrivateFile;
+ EFI_TPL OldTpl;
+
+ Status = EFI_UNSUPPORTED;
+
+ if (This == NULL || Root == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This);
+
+ PrivateFile = AllocatePool (sizeof (EMU_EFI_FILE_PRIVATE));
+ if (PrivateFile == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ PrivateFile->Signature = EMU_EFI_FILE_PRIVATE_SIGNATURE;
+ PrivateFile->IoThunk = Private->IoThunk;
+ PrivateFile->SimpleFileSystem = This;
+
+ ZeroMem (&PrivateFile->EfiFile, sizeof (PrivateFile->EfiFile));
+ PrivateFile->EfiFile.Revision = EFI_FILE_PROTOCOL_REVISION;
+ PrivateFile->EfiFile.Open = EmuSimpleFileSystemOpen;
+ PrivateFile->EfiFile.Close = EmuSimpleFileSystemClose;
+ PrivateFile->EfiFile.Delete = EmuSimpleFileSystemDelete;
+ PrivateFile->EfiFile.Read = EmuSimpleFileSystemRead;
+ PrivateFile->EfiFile.Write = EmuSimpleFileSystemWrite;
+ PrivateFile->EfiFile.GetPosition = EmuSimpleFileSystemGetPosition;
+ PrivateFile->EfiFile.SetPosition = EmuSimpleFileSystemSetPosition;
+ PrivateFile->EfiFile.GetInfo = EmuSimpleFileSystemGetInfo;
+ PrivateFile->EfiFile.SetInfo = EmuSimpleFileSystemSetInfo;
+ PrivateFile->EfiFile.Flush = EmuSimpleFileSystemFlush;
+
+ *Root = &PrivateFile->EfiFile;
+
+ Status = Private->Io->OpenVolume (Private->Io, &PrivateFile->Io);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ AddUnicodeString2 (
+ "eng",
+ gEmuSimpleFileSystemComponentName.SupportedLanguages,
+ &Private->ControllerNameTable,
+ Private->IoThunk->ConfigString,
+ TRUE
+ );
+
+ AddUnicodeString2 (
+ "en",
+ gEmuSimpleFileSystemComponentName.SupportedLanguages,
+ &Private->ControllerNameTable,
+ Private->IoThunk->ConfigString,
+ FALSE
+ );
+
+
+Done:
+ if (EFI_ERROR (Status)) {
+ if (PrivateFile) {
+ gBS->FreePool (PrivateFile);
+ }
+
+ *Root = NULL;
+ }
+
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+/**
+ Tests to see if this driver supports a given controller. If a child device is provided,
+ it further tests to see if this driver supports creating a handle for the specified child device.
+
+ This function checks to see if the driver specified by This supports the device specified by
+ ControllerHandle. Drivers will typically use the device path attached to
+ ControllerHandle and/or the services from the bus I/O abstraction attached to
+ ControllerHandle to determine if the driver supports ControllerHandle. This function
+ may be called many times during platform initialization. In order to reduce boot times, the tests
+ performed by this function must be very small, and take as little time as possible to execute. This
+ function must not change the state of any hardware devices, and this function must be aware that the
+ device specified by ControllerHandle may already be managed by the same driver or a
+ different driver. This function must match its calls to AllocatePages() with FreePages(),
+ AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
+ Because ControllerHandle may have been previously started by the same driver, if a protocol is
+ already in the opened state, then it must not be closed with CloseProtocol(). This is required
+ to guarantee the state of ControllerHandle is not modified by this function.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to test. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For bus drivers, if this parameter is not NULL, then
+ the bus driver must determine if the bus controller specified
+ by ControllerHandle and the child controller specified
+ by RemainingDevicePath are both supported by this
+ bus driver.
+
+ @retval EFI_SUCCESS The device specified by ControllerHandle and
+ RemainingDevicePath is supported by the driver specified by This.
+ @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by the driver
+ specified by This.
+ @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by a different
+ driver or an application that requires exclusive access.
+ Currently not implemented.
+ @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
+ RemainingDevicePath is not supported by the driver specified by This.
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&EmuIoThunk,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Make sure GUID is for a File System handle.
+ //
+ Status = EFI_UNSUPPORTED;
+ if (CompareGuid (EmuIoThunk->Protocol, &gEfiSimpleFileSystemProtocolGuid)) {
+ Status = EFI_SUCCESS;
+ }
+
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return Status;
+}
+
+
+
+/**
+ Starts a device controller or a bus controller.
+
+ The Start() function is designed to be invoked from the EFI boot service ConnectController().
+ As a result, much of the error checking on the parameters to Start() has been moved into this
+ common boot service. It is legal to call Start() from other locations,
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE.
+ 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
+ EFI_DEVICE_PATH_PROTOCOL.
+ 3. Prior to calling Start(), the Supported() function for the driver specified by This must
+ have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to start. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For a bus driver, if this parameter is NULL, then handles
+ for all the children of Controller are created by this driver.
+ If this parameter is not NULL and the first Device Path Node is
+ not the End of Device Path Node, then only the handle for the
+ child device specified by the first Device Path Node of
+ RemainingDevicePath is created by this driver.
+ If the first Device Path Node of RemainingDevicePath is
+ the End of Device Path Node, no child handle is created by this
+ driver.
+
+ @retval EFI_SUCCESS The device was started.
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval Others The driver failded to start the device.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
+ EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private;
+
+ Private = NULL;
+
+ //
+ // Open the IO Abstraction(s) needed
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&EmuIoThunk,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Validate GUID
+ //
+ if (!CompareGuid (EmuIoThunk->Protocol, &gEfiSimpleFileSystemProtocolGuid)) {
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
+
+ Private = AllocateZeroPool (sizeof (EMU_SIMPLE_FILE_SYSTEM_PRIVATE));
+ if (Private == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ Status = EmuIoThunk->Open (EmuIoThunk);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Private->Signature = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE;
+ Private->IoThunk = EmuIoThunk;
+ Private->Io = EmuIoThunk->Interface;
+
+ Private->SimpleFileSystem.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
+ Private->SimpleFileSystem.OpenVolume = EmuSimpleFileSystemOpenVolume;
+
+ Private->ControllerNameTable = NULL;
+
+ AddUnicodeString2 (
+ "eng",
+ gEmuSimpleFileSystemComponentName.SupportedLanguages,
+ &Private->ControllerNameTable,
+ EmuIoThunk->ConfigString,
+ TRUE
+ );
+
+ AddUnicodeString2 (
+ "en",
+ gEmuSimpleFileSystemComponentName2.SupportedLanguages,
+ &Private->ControllerNameTable,
+ EmuIoThunk->ConfigString,
+ FALSE
+ );
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ControllerHandle,
+ &gEfiSimpleFileSystemProtocolGuid, &Private->SimpleFileSystem,
+ NULL
+ );
+
+Done:
+ if (EFI_ERROR (Status)) {
+ if (Private != NULL) {
+ if (Private->ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+ }
+
+ gBS->FreePool (Private);
+
+ }
+
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+ }
+
+ return Status;
+}
+
+
+/**
+ Stops a device controller or a bus controller.
+
+ The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
+ As a result, much of the error checking on the parameters to Stop() has been moved
+ into this common boot service. It is legal to call Stop() from other locations,
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
+ same driver's Start() function.
+ 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
+ EFI_HANDLE. In addition, all of these handles must have been created in this driver's
+ Start() function, and the Start() function must have called OpenProtocol() on
+ ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must
+ support a bus specific I/O protocol for the driver
+ to use to stop the device.
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
+ if NumberOfChildren is 0.
+
+ @retval EFI_SUCCESS The device was stopped.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSimpleFileSystemDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
+ EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private;
+
+ //
+ // Get our context back
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID **)&SimpleFileSystem,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (SimpleFileSystem);
+
+ //
+ // Uninstall the Simple File System Protocol from ControllerHandle
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ControllerHandle,
+ &gEfiSimpleFileSystemProtocolGuid, &Private->SimpleFileSystem,
+ NULL
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Destroy the IO interface.
+ //
+ Status = Private->IoThunk->Close (Private->IoThunk);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Free our instance data
+ //
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+ gBS->FreePool (Private);
+ }
+
+ return Status;
+}
+
+
+EFI_DRIVER_BINDING_PROTOCOL gEmuSimpleFileSystemDriverBinding = {
+ EmuSimpleFileSystemDriverBindingSupported,
+ EmuSimpleFileSystemDriverBindingStart,
+ EmuSimpleFileSystemDriverBindingStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+
+
+
+/**
+ The user Entry Point for module EmuSimpleFileSystem. 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
+InitializeEmuSimpleFileSystem(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &gEmuSimpleFileSystemDriverBinding,
+ ImageHandle,
+ &gEmuSimpleFileSystemComponentName,
+ &gEmuSimpleFileSystemComponentName2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.h b/CdeEmuPkg/EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.h
new file mode 100644
index 00000000000..8ab57f9b570
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystem.h
@@ -0,0 +1,74 @@
+/*++ @file
+ Produce Simple File System abstractions for a directory on your PC using Unix APIs.
+ The configuration of what devices to mount or emulate comes from
+ environment variables.
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef _EMU_SIMPLE_FILE_SYSTEM_H_
+#define _EMU_SIMPLE_FILE_SYSTEM_H_
+
+#include "PiDxe.h"
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+extern EFI_DRIVER_BINDING_PROTOCOL gEmuSimpleFileSystemDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gEmuSimpleFileSystemComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gEmuSimpleFileSystemComponentName2;
+
+#define EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'M', 'f', 's')
+
+typedef struct {
+ UINTN Signature;
+ EMU_IO_THUNK_PROTOCOL *IoThunk;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystem;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Io;
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+} EMU_SIMPLE_FILE_SYSTEM_PRIVATE;
+
+#define EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS(a) \
+ CR (a, \
+ EMU_SIMPLE_FILE_SYSTEM_PRIVATE, \
+ SimpleFileSystem, \
+ EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE \
+ )
+
+#define EMU_EFI_FILE_PRIVATE_SIGNATURE SIGNATURE_32 ('e', 'm', 'f', 's')
+
+typedef struct {
+ UINTN Signature;
+ EMU_IO_THUNK_PROTOCOL *IoThunk;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem;
+ EFI_FILE_PROTOCOL EfiFile;
+ EFI_FILE_PROTOCOL *Io;
+} EMU_EFI_FILE_PRIVATE;
+
+#define EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS(a) \
+ CR (a, \
+ EMU_EFI_FILE_PRIVATE, \
+ EfiFile, \
+ EMU_EFI_FILE_PRIVATE_SIGNATURE \
+ )
+
+
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf b/CdeEmuPkg/EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf
new file mode 100644
index 00000000000..d204ba6a084
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf
@@ -0,0 +1,50 @@
+## @file
+# Simple filesystem driver
+#
+# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EmuSimpleFileSystem
+ FILE_GUID = 35B72237-3926-CF4A-A7F3-1449F9E0E4BD
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeEmuSimpleFileSystem
+
+
+[Sources]
+ ComponentName.c
+ EmuSimpleFileSystem.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ UefiLib
+ UefiDriverEntryPoint
+ BaseLib
+ DebugLib
+
+
+[Guids]
+ gEfiFileSystemVolumeLabelInfoIdGuid # SOMETIMES_CONSUMED
+ gEfiFileInfoGuid # SOMETIMES_CONSUMED
+ gEfiFileSystemInfoGuid # SOMETIMES_CONSUMED
+
+
+[Protocols]
+ gEfiSimpleFileSystemProtocolGuid # PROTOCOL BY_START
+ gEmuIoThunkProtocolGuid # PROTOCOL TO_START
+
diff --git a/CdeEmuPkg/EmulatorPkg/EmuSnpDxe/ComponentName.c b/CdeEmuPkg/EmulatorPkg/EmuSnpDxe/ComponentName.c
new file mode 100644
index 00000000000..91b70b92317
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuSnpDxe/ComponentName.c
@@ -0,0 +1,312 @@
+/** @file
+
+ Copyright (c) 2010, Apple, Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+-**/
+
+#include "EmuSnpDxe.h"
+
+//
+// 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
+EmuSnpDriverComponentNameGetDriverName (
+ 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
+EmuSnpDriverComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gEmuSnpDriverComponentName = {
+ EmuSnpDriverComponentNameGetDriverName,
+ EmuSnpDriverComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gEmuSnpDriverComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) EmuSnpDriverComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) EmuSnpDriverComponentNameGetControllerName,
+ "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mEmuSnpDriverNameTable[] = {
+ {
+ "eng;en",
+ L"Emu SNP Driver"
+ },
+ {
+ 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
+EmuSnpDriverComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mEmuSnpDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gEmuSnpDriverComponentName)
+ );
+}
+
+/**
+ 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
+EmuSnpDriverComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/EmuSnpDxe/EmuSnpDxe.c b/CdeEmuPkg/EmulatorPkg/EmuSnpDxe/EmuSnpDxe.c
new file mode 100644
index 00000000000..2cb87fba6fc
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuSnpDxe/EmuSnpDxe.c
@@ -0,0 +1,996 @@
+/** @file
+
+ Copyright (c) 2010, Apple, Inc. All rights reserved.
+ Copyright (c) 2011, Intel Corporation. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+ EmuSnp.c
+
+Abstract:
+
+-**/
+
+#include "EmuSnpDxe.h"
+
+
+
+EFI_SIMPLE_NETWORK_PROTOCOL gEmuSnpTemplate = {
+ EFI_SIMPLE_NETWORK_PROTOCOL_REVISION,
+ EmuSnpStart,
+ EmuSnpStop,
+ EmuSnpInitialize,
+ EmuSnpReset,
+ EmuSnpShutdown,
+ EmuSnpReceiveFilters,
+ EmuSnpStationAddress,
+ EmuSnpStatistics,
+ EmuSnpMcastIptoMac,
+ EmuSnpNvdata,
+ EmuSnpGetStatus,
+ EmuSnpTransmit,
+ EmuSnpReceive,
+ NULL, // WaitForPacket
+ NULL // Mode
+ };
+
+EFI_SIMPLE_NETWORK_MODE gEmuSnpModeTemplate = {
+ EfiSimpleNetworkStopped, // State
+ NET_ETHER_ADDR_LEN, // HwAddressSize
+ NET_ETHER_HEADER_SIZE, // MediaHeaderSize
+ 1500, // MaxPacketSize
+ 0, // NvRamSize
+ 0, // NvRamAccessSize
+ 0, // ReceiveFilterMask
+ 0, // ReceiveFilterSetting
+ MAX_MCAST_FILTER_CNT, // MaxMCastFilterCount
+ 0, // MCastFilterCount
+ {
+ { { 0 } }
+ }, // MCastFilter
+ {
+ { 0 }
+ }, // CurrentAddress
+ {
+ { 0 }
+ }, // BroadcastAddress
+ {
+ { 0 }
+ }, // PermanentAddress
+ NET_IFTYPE_ETHERNET, // IfType
+ FALSE, // MacAddressChangeable
+ FALSE, // MultipleTxSupported
+ FALSE, // MediaPresentSupported
+ TRUE // MediaPresent
+};
+
+
+/**
+ Changes the state of a network interface from "stopped" to "started".
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpStart(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private;
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (This);
+
+ Status = Private->Io->Start (Private->Io);
+ return Status;
+}
+
+
+/**
+ Changes the state of a network interface from "started" to "stopped".
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpStop (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private;
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (This);
+
+ Status = Private->Io->Stop (Private->Io);
+ return Status;
+}
+
+
+/**
+ Resets a network adapter and allocates the transmit and receive buffers
+ required by the network interface; optionally, also requests allocation
+ of additional transmit and receive buffers.
+
+ @param This Protocol instance pointer.
+ @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space
+ that the driver should allocate for the network interface.
+ Some network interfaces will not be able to use the extra
+ buffer, and the caller will not know if it is actually
+ being used.
+ @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space
+ that the driver should allocate for the network interface.
+ Some network interfaces will not be able to use the extra
+ buffer, and the caller will not know if it is actually
+ being used.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpInitialize (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN UINTN ExtraRxBufferSize OPTIONAL,
+ IN UINTN ExtraTxBufferSize OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private;
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (This);
+
+ Status = Private->Io->Initialize (Private->Io, ExtraRxBufferSize, ExtraTxBufferSize);
+ return Status;
+}
+
+/**
+ Resets a network adapter and re-initializes it with the parameters that were
+ provided in the previous call to Initialize().
+
+ @param This Protocol instance pointer.
+ @param ExtendedVerification Indicates that the driver may perform a more
+ exhaustive verification operation of the device
+ during reset.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpReset (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private;
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (This);
+
+ Status = Private->Io->Reset (Private->Io, ExtendedVerification);
+ return Status;
+}
+
+/**
+ Resets a network adapter and leaves it in a state that is safe for
+ another driver to initialize.
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpShutdown (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private;
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (This);
+
+ Status = Private->Io->Shutdown (Private->Io);
+ return Status;
+}
+
+/**
+ Manages the multicast receive filters of a network interface.
+
+ @param This Protocol instance pointer.
+ @param EnableBits A bit mask of receive filters to enable on the network interface.
+ @param DisableBits A bit mask of receive filters to disable on the network interface.
+ @param ResetMcastFilter Set to TRUE to reset the contents of the multicast receive
+ filters on the network interface to their default values.
+ @param McastFilterCount Number of multicast HW MAC addresses in the new
+ MCastFilter list. This value must be less than or equal to
+ the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This
+ field is optional if ResetMCastFilter is TRUE.
+ @param McastFilter A pointer to a list of new multicast receive filter HW MAC
+ addresses. This list will replace any existing multicast
+ HW MAC address list. This field is optional if
+ ResetMCastFilter is TRUE.
+
+ @retval EFI_SUCCESS The multicast receive filter list was updated.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpReceiveFilters (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN UINT32 EnableBits,
+ IN UINT32 DisableBits,
+ IN BOOLEAN ResetMcastFilter,
+ IN UINTN McastFilterCount OPTIONAL,
+ IN EFI_MAC_ADDRESS *McastFilter OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private;
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (This);
+
+ Status = Private->Io->ReceiveFilters (
+ Private->Io,
+ EnableBits,
+ DisableBits,
+ ResetMcastFilter,
+ McastFilterCount,
+ McastFilter
+ );
+ return Status;
+}
+
+/**
+ Modifies or resets the current station address, if supported.
+
+ @param This Protocol instance pointer.
+ @param Reset Flag used to reset the station address to the network interfaces
+ permanent address.
+ @param NewMacAddr New station address to be used for the network interface.
+
+ @retval EFI_UNSUPPORTED Not supported yet.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpStationAddress (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN BOOLEAN Reset,
+ IN EFI_MAC_ADDRESS *NewMacAddr OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private;
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (This);
+
+ Status = Private->Io->StationAddress (Private->Io, Reset, NewMacAddr);
+ return Status;
+}
+
+/**
+ Resets or collects the statistics on a network interface.
+
+ @param This Protocol instance pointer.
+ @param Reset Set to TRUE to reset the statistics for the network interface.
+ @param StatisticsSize On input the size, in bytes, of StatisticsTable. On
+ output the size, in bytes, of the resulting table of
+ statistics.
+ @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
+ contains the statistics.
+
+ @retval EFI_SUCCESS The statistics were collected from the network interface.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer
+ size needed to hold the statistics is returned in
+ StatisticsSize.
+ @retval EFI_UNSUPPORTED Not supported yet.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpStatistics (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN BOOLEAN Reset,
+ IN OUT UINTN *StatisticsSize OPTIONAL,
+ OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private;
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (This);
+
+ Status = Private->Io->Statistics (Private->Io, Reset, StatisticsSize, StatisticsTable);
+ return Status;
+}
+
+/**
+ Converts a multicast IP address to a multicast HW MAC address.
+
+ @param This Protocol instance pointer.
+ @param Ipv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set
+ to FALSE if the multicast IP address is IPv4 [RFC 791].
+ @param Ip The multicast IP address that is to be converted to a multicast
+ HW MAC address.
+ @param Mac The multicast HW MAC address that is to be generated from IP.
+
+ @retval EFI_SUCCESS The multicast IP address was mapped to the multicast
+ HW MAC address.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer
+ size needed to hold the statistics is returned in
+ StatisticsSize.
+ @retval EFI_UNSUPPORTED Not supported yet.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpMcastIptoMac (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN BOOLEAN Ipv6,
+ IN EFI_IP_ADDRESS *Ip,
+ OUT EFI_MAC_ADDRESS *Mac
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private;
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (This);
+
+ Status = Private->Io->MCastIpToMac (Private->Io, Ipv6, Ip, Mac);
+ return Status;
+}
+
+
+/**
+ Performs read and write operations on the NVRAM device attached to a
+ network interface.
+
+ @param This Protocol instance pointer.
+ @param ReadOrWrite TRUE for read operations, FALSE for write operations.
+ @param Offset Byte offset in the NVRAM device at which to start the read or
+ write operation. This must be a multiple of NvRamAccessSize and
+ less than NvRamSize.
+ @param BufferSize The number of bytes to read or write from the NVRAM device.
+ This must also be a multiple of NvramAccessSize.
+ @param Buffer A pointer to the data buffer.
+
+ @retval EFI_UNSUPPORTED Not supported yet.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpNvdata (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN BOOLEAN ReadOrWrite,
+ IN UINTN Offset,
+ IN UINTN BufferSize,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private;
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (This);
+
+ Status = Private->Io->NvData (Private->Io, ReadOrWrite, Offset, BufferSize, Buffer);
+ return Status;
+}
+
+
+/**
+ Reads the current interrupt status and recycled transmit buffer status from
+ a network interface.
+
+ @param This Protocol instance pointer.
+ @param InterruptStatus A pointer to the bit mask of the currently active interrupts
+ If this is NULL, the interrupt status will not be read from
+ the device. If this is not NULL, the interrupt status will
+ be read from the device. When the interrupt status is read,
+ it will also be cleared. Clearing the transmit interrupt
+ does not empty the recycled transmit buffer array.
+ @param TxBuffer Recycled transmit buffer address. The network interface will
+ not transmit if its internal recycled transmit buffer array
+ is full. Reading the transmit buffer does not clear the
+ transmit interrupt. If this is NULL, then the transmit buffer
+ status will not be read. If there are no transmit buffers to
+ recycle and TxBuf is not NULL, * TxBuf will be set to NULL.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpGetStatus (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ OUT UINT32 *InterruptStatus,
+ OUT VOID **TxBuffer
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private;
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (This);
+
+ Status = Private->Io->GetStatus (Private->Io, InterruptStatus, TxBuffer);
+ return Status;
+}
+
+
+/**
+ Places a packet in the transmit queue of a network interface.
+
+ @param This Protocol instance pointer.
+ @param HeaderSize The size, in bytes, of the media header to be filled in by
+ the Transmit() function. If HeaderSize is non-zero, then it
+ must be equal to This->Mode->MediaHeaderSize and the DestAddr
+ and Protocol parameters must not be NULL.
+ @param BufferSize The size, in bytes, of the entire packet (media header and
+ data) to be transmitted through the network interface.
+ @param Buffer A pointer to the packet (media header followed by data) to be
+ transmitted. This parameter cannot be NULL. If HeaderSize is zero,
+ then the media header in Buffer must already be filled in by the
+ caller. If HeaderSize is non-zero, then the media header will be
+ filled in by the Transmit() function.
+ @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter
+ is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then
+ This->Mode->CurrentAddress is used for the source HW MAC address.
+ @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this
+ parameter is ignored.
+ @param Protocol The type of header to build. If HeaderSize is zero, then this
+ parameter is ignored. See RFC 1700, section "Ether Types", for
+ examples.
+
+ @retval EFI_SUCCESS The packet was placed on the transmit queue.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpTransmit (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN UINTN HeaderSize,
+ IN UINTN BufferSize,
+ IN VOID* Buffer,
+ IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
+ IN EFI_MAC_ADDRESS *DestAddr OPTIONAL,
+ IN UINT16 *Protocol OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private;
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (This);
+
+ Status = Private->Io->Transmit (
+ Private->Io,
+ HeaderSize,
+ BufferSize,
+ Buffer,
+ SrcAddr,
+ DestAddr,
+ Protocol
+ );
+ return Status;
+}
+
+/**
+ Receives a packet from a network interface.
+
+ @param This Protocol instance pointer.
+ @param HeaderSize The size, in bytes, of the media header received on the network
+ interface. If this parameter is NULL, then the media header size
+ will not be returned.
+ @param BuffSize On entry, the size, in bytes, of Buffer. On exit, the size, in
+ bytes, of the packet that was received on the network interface.
+ @param Buffer A pointer to the data buffer to receive both the media header and
+ the data.
+ @param SourceAddr The source HW MAC address. If this parameter is NULL, the
+ HW MAC source address will not be extracted from the media
+ header.
+ @param DestinationAddr The destination HW MAC address. If this parameter is NULL,
+ the HW MAC destination address will not be extracted from the
+ media header.
+ @param Protocol The media header type. If this parameter is NULL, then the
+ protocol will not be extracted from the media header. See
+ RFC 1700 section "Ether Types" for examples.
+
+ @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has
+ been updated to the number of bytes received.
+ @retval EFI_NOT_READY The network interface is too busy to accept this transmit
+ request.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpReceive (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ OUT UINTN *HeaderSize OPTIONAL,
+ IN OUT UINTN *BuffSize,
+ OUT VOID *Buffer,
+ OUT EFI_MAC_ADDRESS *SourceAddr OPTIONAL,
+ OUT EFI_MAC_ADDRESS *DestinationAddr OPTIONAL,
+ OUT UINT16 *Protocol OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private;
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (This);
+
+ Status = Private->Io->Receive (
+ Private->Io,
+ HeaderSize,
+ BuffSize,
+ Buffer,
+ SourceAddr,
+ DestinationAddr,
+ Protocol
+ );
+ return Status;
+}
+
+
+
+/**
+ Test to see if this driver supports ControllerHandle. This service
+ is called by the EFI boot service ConnectController(). In
+ order to make drivers as small as possible, there are a few calling
+ restrictions for this service. ConnectController() must
+ follow these calling restrictions. If any other agent wishes to call
+ Supported() it must also follow these calling restrictions.
+
+ @param This Protocol instance pointer.
+ @param ControllerHandle Handle of device to test
+ @param RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver supports this device
+ @retval EFI_UNSUPPORTED This driver does not support this device
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
+ MAC_ADDR_DEVICE_PATH *Node;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+
+ if (RemainingDevicePath != NULL) {
+ if (!IsDevicePathEnd (RemainingDevicePath)) {
+ Node = (MAC_ADDR_DEVICE_PATH *)RemainingDevicePath;
+ if (Node->Header.Type != MESSAGING_DEVICE_PATH ||
+ Node->Header.SubType != MSG_MAC_ADDR_DP) {
+ // If the remaining device path does not match we don't support the request
+ return EFI_UNSUPPORTED;
+ }
+ }
+ }
+
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&EmuIoThunk,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+
+ //
+ // Open the EFI Device Path protocol needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Make sure GUID is for a SNP handle.
+ //
+ Status = EFI_UNSUPPORTED;
+ if (CompareGuid (EmuIoThunk->Protocol, &gEmuSnpProtocolGuid)) {
+ Status = EFI_SUCCESS;
+ }
+
+ //
+ // Close protocol, don't use device path protocol in the Support() function
+ //
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return Status;
+}
+
+
+/**
+ Start this driver on ControllerHandle. This service is called by the
+ EFI boot service ConnectController(). In order to make
+ drivers as small as possible, there are a few calling restrictions for
+ this service. ConnectController() must follow these
+ calling restrictions. If any other agent wishes to call Start() it
+ must also follow these calling restrictions.
+
+ @param This Protocol instance pointer.
+ @param ControllerHandle Handle of device to bind driver to
+ @param RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EMU_IO_THUNK_PROTOCOL *EmuIoThunk;
+ EMU_SNP_PRIVATE_DATA *Private;
+ MAC_ADDR_DEVICE_PATH Node;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+
+ Private = NULL;
+
+ //
+ // Grab the protocols we need
+ //
+ Status = gBS->OpenProtocol(
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ ( VOID ** ) &ParentDevicePath,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && Status) {
+ return Status;
+ }
+
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&EmuIoThunk,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (!CompareGuid (EmuIoThunk->Protocol, &gEmuSnpProtocolGuid)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = EmuIoThunk->Open (EmuIoThunk);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Allocate the private data.
+ //
+ Private = AllocateZeroPool (sizeof (EMU_SNP_PRIVATE_DATA));
+ if (Private == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ CopyMem (&Private->Snp, &gEmuSnpTemplate, sizeof (EFI_SIMPLE_NETWORK_PROTOCOL));
+ CopyMem (&Private->Mode, &gEmuSnpModeTemplate, sizeof (EFI_SIMPLE_NETWORK_MODE));
+
+ Private->Signature = EMU_SNP_PRIVATE_DATA_SIGNATURE;
+ Private->IoThunk = EmuIoThunk;
+ Private->Io = EmuIoThunk->Interface;
+ Private->EfiHandle = ControllerHandle;
+ Private->DeviceHandle = NULL;
+ Private->Snp.Mode = &Private->Mode;
+ Private->ControllerNameTable = NULL;
+
+
+ Status = Private->Io->CreateMapping (Private->Io, &Private->Mode);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Build the device path by appending the MAC node to the ParentDevicePath
+ // from the EmuIo handle.
+ //
+ ZeroMem (&Node, sizeof (MAC_ADDR_DEVICE_PATH));
+
+ Node.Header.Type = MESSAGING_DEVICE_PATH;
+ Node.Header.SubType = MSG_MAC_ADDR_DP;
+ Node.IfType = Private->Mode.IfType;
+
+ SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL * )&Node, sizeof (MAC_ADDR_DEVICE_PATH));
+
+ CopyMem (&Node.MacAddress, &Private->Mode.CurrentAddress, sizeof (EFI_MAC_ADDRESS));
+
+ //
+ // Build the device path by appending the MAC node to the ParentDevicePath from the EmuIo handle.
+ //
+ Private->DevicePath = AppendDevicePathNode (ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&Node);
+ if ( Private->DevicePath == NULL ) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ AddUnicodeString2 (
+ "eng",
+ gEmuSnpDriverComponentName.SupportedLanguages,
+ &Private->ControllerNameTable,
+ EmuIoThunk->ConfigString,
+ TRUE
+ );
+
+ AddUnicodeString2 (
+ "en",
+ gEmuSnpDriverComponentName2.SupportedLanguages,
+ &Private->ControllerNameTable,
+ EmuIoThunk->ConfigString,
+ FALSE
+ );
+
+ //
+ // Create Child Handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &Private->DeviceHandle,
+ &gEfiSimpleNetworkProtocolGuid, &Private->Snp,
+ &gEfiDevicePathProtocolGuid, Private->DevicePath,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Open For Child Device
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ (VOID **)&EmuIoThunk,
+ This->DriverBindingHandle,
+ Private->DeviceHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+
+Done:
+ if (EFI_ERROR (Status)) {
+ if (Private != NULL) {
+ FreePool (Private);
+ }
+ if (ParentDevicePath != NULL) {
+ gBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Stop this driver on ControllerHandle. This service is called by the
+ EFI boot service DisconnectController(). In order to
+ make drivers as small as possible, there are a few calling
+ restrictions for this service. DisconnectController()
+ must follow these calling restrictions. If any other agent wishes
+ to call Stop() it must also follow these calling restrictions.
+
+ @param This Protocol instance pointer.
+ @param ControllerHandle Handle of device to stop driver on
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
+ children is zero stop the entire bus driver.
+ @param ChildHandleBuffer List of Child Handles to Stop.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ EMU_SNP_PRIVATE_DATA *Private = NULL;
+ EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
+ VOID *EmuIoThunk;
+
+ //
+ // Complete all outstanding transactions to Controller.
+ // Don't allow any new transaction to Controller to be started.
+ //
+ if (NumberOfChildren == 0) {
+ //
+ // Close the bus driver
+ //
+ Status = gBS->CloseProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ Status = gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+ return Status;
+ }
+
+ ASSERT (NumberOfChildren == 1);
+
+
+ //
+ // Get our context back.
+ //
+ Status = gBS->OpenProtocol(
+ ChildHandleBuffer[0],
+ &gEfiSimpleNetworkProtocolGuid,
+ ( VOID ** ) &Snp,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Private = EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS (Snp);
+ ASSERT (Private->DeviceHandle == ChildHandleBuffer[0]);
+ ASSERT (Private->EfiHandle == ControllerHandle);
+
+ Status = gBS->CloseProtocol(
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ This->DriverBindingHandle,
+ Private->DeviceHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->UninstallMultipleProtocolInterfaces(
+ Private->DeviceHandle,
+ &gEfiSimpleNetworkProtocolGuid, &Private->Snp,
+ &gEfiDevicePathProtocolGuid, Private->DevicePath,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->OpenProtocol (
+ ControllerHandle,
+ &gEmuIoThunkProtocolGuid,
+ &EmuIoThunk,
+ This->DriverBindingHandle,
+ Private->DeviceHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ } else {
+ Status = Private->IoThunk->Close (Private->IoThunk);
+ ASSERT_EFI_ERROR (Status);
+
+ FreePool (Private->DevicePath);
+ FreeUnicodeStringTable (Private->ControllerNameTable);
+ FreePool (Private);
+ }
+
+ return Status;
+}
+
+
+EFI_DRIVER_BINDING_PROTOCOL gEmuSnpDriverBinding = {
+ EmuSnpDriverBindingSupported,
+ EmuSnpDriverBindingStart,
+ EmuSnpDriverBindingStop,
+ 0xA,
+ NULL,
+ NULL
+};
+
+
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+ both device drivers and bus drivers.
+
+ @param ImageHandle The firmware allocated handle for the UEFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeEmuSnpDriver (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install the Driver Protocols
+ //
+ Status = EfiLibInstallDriverBindingComponentName2(
+ ImageHandle,
+ SystemTable,
+ &gEmuSnpDriverBinding,
+ ImageHandle,
+ &gEmuSnpDriverComponentName,
+ &gEmuSnpDriverComponentName2
+ );
+
+ return Status;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/EmuSnpDxe/EmuSnpDxe.h b/CdeEmuPkg/EmulatorPkg/EmuSnpDxe/EmuSnpDxe.h
new file mode 100644
index 00000000000..71df6f319d8
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuSnpDxe/EmuSnpDxe.h
@@ -0,0 +1,482 @@
+/** @file
+
+ Copyright (c) 2010, Apple, Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+Module Name:
+
+ EmuSnp.h
+
+Abstract:
+
+-**/
+
+#ifndef _EMU_SNP_H_
+#define _EMU_SNP_H_
+
+#include
+
+#include
+#include
+#include
+#include
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define NET_ETHER_HEADER_SIZE 14
+
+//
+// Private data for driver.
+//
+#define EMU_SNP_PRIVATE_DATA_SIGNATURE SIGNATURE_32( 'U', 'S', 'N', 'P' )
+
+typedef struct {
+ UINTN Signature;
+ EMU_IO_THUNK_PROTOCOL *IoThunk;
+ EMU_SNP_PROTOCOL *Io;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ EFI_HANDLE EfiHandle;
+ EFI_HANDLE DeviceHandle;
+
+ EFI_SIMPLE_NETWORK_PROTOCOL Snp;
+ EFI_SIMPLE_NETWORK_MODE Mode;
+
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+
+} EMU_SNP_PRIVATE_DATA;
+
+#define EMU_SNP_PRIVATE_DATA_FROM_SNP_THIS(a) \
+ CR( a, EMU_SNP_PRIVATE_DATA, Snp, EMU_SNP_PRIVATE_DATA_SIGNATURE )
+
+extern EFI_DRIVER_BINDING_PROTOCOL gEmuSnpDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gEmuSnpDriverComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gEmuSnpDriverComponentName2;
+
+/**
+ Test to see if this driver supports ControllerHandle. This service
+ is called by the EFI boot service ConnectController(). In
+ order to make drivers as small as possible, there are a few calling
+ restrictions for this service. ConnectController() must
+ follow these calling restrictions. If any other agent wishes to call
+ Supported() it must also follow these calling restrictions.
+
+ @param This Protocol instance pointer.
+ @param ControllerHandle Handle of device to test
+ @param RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS This driver supports this device
+ @retval EFI_UNSUPPORTED This driver does not support this device
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL * This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
+ );
+
+/**
+ Start this driver on ControllerHandle. This service is called by the
+ EFI boot service ConnectController(). In order to make
+ drivers as small as possible, there are a few calling restrictions for
+ this service. ConnectController() must follow these
+ calling restrictions. If any other agent wishes to call Start() it
+ must also follow these calling restrictions.
+
+ @param This Protocol instance pointer.
+ @param ControllerHandle Handle of device to bind driver to
+ @param RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL * This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
+ );
+
+/**
+ Stop this driver on ControllerHandle. This service is called by the
+ EFI boot service DisconnectController(). In order to
+ make drivers as small as possible, there are a few calling
+ restrictions for this service. DisconnectController()
+ must follow these calling restrictions. If any other agent wishes
+ to call Stop() it must also follow these calling restrictions.
+
+ @param This Protocol instance pointer.
+ @param ControllerHandle Handle of device to stop driver on
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
+ children is zero stop the entire bus driver.
+ @param ChildHandleBuffer List of Child Handles to Stop.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+/**
+ Changes the state of a network interface from "stopped" to "started".
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpStart(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This
+ );
+
+/**
+ Changes the state of a network interface from "started" to "stopped".
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpStop(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This
+ );
+
+/**
+ Resets a network adapter and allocates the transmit and receive buffers
+ required by the network interface; optionally, also requests allocation
+ of additional transmit and receive buffers.
+
+ @param This Protocol instance pointer.
+ @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space
+ that the driver should allocate for the network interface.
+ Some network interfaces will not be able to use the extra
+ buffer, and the caller will not know if it is actually
+ being used.
+ @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space
+ that the driver should allocate for the network interface.
+ Some network interfaces will not be able to use the extra
+ buffer, and the caller will not know if it is actually
+ being used.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpInitialize(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ IN UINTN ExtraRxBufferSize OPTIONAL,
+ IN UINTN ExtraTxBufferSize OPTIONAL
+ );
+
+/**
+ Resets a network adapter and re-initializes it with the parameters that were
+ provided in the previous call to Initialize().
+
+ @param This Protocol instance pointer.
+ @param ExtendedVerification Indicates that the driver may perform a more
+ exhaustive verification operation of the device
+ during reset.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpReset(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+/**
+ Resets a network adapter and leaves it in a state that is safe for
+ another driver to initialize.
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpShutdown(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This
+ );
+
+/**
+ Manages the multicast receive filters of a network interface.
+
+ @param This Protocol instance pointer.
+ @param EnableBits A bit mask of receive filters to enable on the network interface.
+ @param DisableBits A bit mask of receive filters to disable on the network interface.
+ @param ResetMcastFilter Set to TRUE to reset the contents of the multicast receive
+ filters on the network interface to their default values.
+ @param McastFilterCount Number of multicast HW MAC addresses in the new
+ MCastFilter list. This value must be less than or equal to
+ the MCastFilterCnt field of EFI_SIMPLE_NETWORK_MODE. This
+ field is optional if ResetMCastFilter is TRUE.
+ @param McastFilter A pointer to a list of new multicast receive filter HW MAC
+ addresses. This list will replace any existing multicast
+ HW MAC address list. This field is optional if
+ ResetMCastFilter is TRUE.
+
+ @retval EFI_SUCCESS The multicast receive filter list was updated.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpReceiveFilters(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ IN UINT32 EnableBits,
+ IN UINT32 DisableBits,
+ IN BOOLEAN ResetMcastFilter,
+ IN UINTN McastFilterCount OPTIONAL,
+ IN EFI_MAC_ADDRESS* McastFilter OPTIONAL
+ );
+
+/**
+ Modifies or resets the current station address, if supported.
+
+ @param This Protocol instance pointer.
+ @param Reset Flag used to reset the station address to the network interfaces
+ permanent address.
+ @param NewMacAddr New station address to be used for the network interface.
+
+ @retval EFI_UNSUPPORTED Not supported yet.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpStationAddress(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ IN BOOLEAN Reset,
+ IN EFI_MAC_ADDRESS* NewMacAddr OPTIONAL
+ );
+
+/**
+ Resets or collects the statistics on a network interface.
+
+ @param This Protocol instance pointer.
+ @param Reset Set to TRUE to reset the statistics for the network interface.
+ @param StatisticsSize On input the size, in bytes, of StatisticsTable. On
+ output the size, in bytes, of the resulting table of
+ statistics.
+ @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
+ contains the statistics.
+
+ @retval EFI_SUCCESS The statistics were collected from the network interface.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer
+ size needed to hold the statistics is returned in
+ StatisticsSize.
+ @retval EFI_UNSUPPORTED Not supported yet.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpStatistics(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ IN BOOLEAN Reset,
+ IN OUT UINTN* StatisticsSize OPTIONAL,
+ OUT EFI_NETWORK_STATISTICS* StatisticsTable OPTIONAL
+ );
+
+/**
+ Converts a multicast IP address to a multicast HW MAC address.
+
+ @param This Protocol instance pointer.
+ @param Ipv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set
+ to FALSE if the multicast IP address is IPv4 [RFC 791].
+ @param Ip The multicast IP address that is to be converted to a multicast
+ HW MAC address.
+ @param Mac The multicast HW MAC address that is to be generated from IP.
+
+ @retval EFI_SUCCESS The multicast IP address was mapped to the multicast
+ HW MAC address.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer
+ size needed to hold the statistics is returned in
+ StatisticsSize.
+ @retval EFI_UNSUPPORTED Not supported yet.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpMcastIptoMac(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ IN BOOLEAN Ipv6,
+ IN EFI_IP_ADDRESS* Ip,
+ OUT EFI_MAC_ADDRESS* Mac
+ );
+
+/**
+ Performs read and write operations on the NVRAM device attached to a
+ network interface.
+
+ @param This Protocol instance pointer.
+ @param ReadOrWrite TRUE for read operations, FALSE for write operations.
+ @param Offset Byte offset in the NVRAM device at which to start the read or
+ write operation. This must be a multiple of NvRamAccessSize and
+ less than NvRamSize.
+ @param BufferSize The number of bytes to read or write from the NVRAM device.
+ This must also be a multiple of NvramAccessSize.
+ @param Buffer A pointer to the data buffer.
+
+ @retval EFI_UNSUPPORTED Not supported yet.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpNvdata(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ IN BOOLEAN ReadOrWrite,
+ IN UINTN Offset,
+ IN UINTN BufferSize,
+ IN OUT VOID* Buffer
+ );
+
+/**
+ Reads the current interrupt status and recycled transmit buffer status from
+ a network interface.
+
+ @param This Protocol instance pointer.
+ @param InterruptStatus A pointer to the bit mask of the currently active interrupts
+ If this is NULL, the interrupt status will not be read from
+ the device. If this is not NULL, the interrupt status will
+ be read from the device. When the interrupt status is read,
+ it will also be cleared. Clearing the transmit interrupt
+ does not empty the recycled transmit buffer array.
+ @param TxBuffer Recycled transmit buffer address. The network interface will
+ not transmit if its internal recycled transmit buffer array
+ is full. Reading the transmit buffer does not clear the
+ transmit interrupt. If this is NULL, then the transmit buffer
+ status will not be read. If there are no transmit buffers to
+ recycle and TxBuf is not NULL, * TxBuf will be set to NULL.
+
+ @retval EFI_SUCCESS Always succeeds.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpGetStatus(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ OUT UINT32* InterruptStatus,
+ OUT VOID** TxBuffer
+ );
+
+/**
+ Places a packet in the transmit queue of a network interface.
+
+ @param This Protocol instance pointer.
+ @param HeaderSize The size, in bytes, of the media header to be filled in by
+ the Transmit() function. If HeaderSize is non-zero, then it
+ must be equal to This->Mode->MediaHeaderSize and the DestAddr
+ and Protocol parameters must not be NULL.
+ @param BufferSize The size, in bytes, of the entire packet (media header and
+ data) to be transmitted through the network interface.
+ @param Buffer A pointer to the packet (media header followed by data) to be
+ transmitted. This parameter cannot be NULL. If HeaderSize is zero,
+ then the media header in Buffer must already be filled in by the
+ caller. If HeaderSize is non-zero, then the media header will be
+ filled in by the Transmit() function.
+ @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter
+ is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then
+ This->Mode->CurrentAddress is used for the source HW MAC address.
+ @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this
+ parameter is ignored.
+ @param Protocol The type of header to build. If HeaderSize is zero, then this
+ parameter is ignored. See RFC 1700, section "Ether Types", for
+ examples.
+
+ @retval EFI_SUCCESS The packet was placed on the transmit queue.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_ACCESS_DENIED Error acquire global lock for operation.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpTransmit(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ IN UINTN HeaderSize,
+ IN UINTN BufferSize,
+ IN VOID* Buffer,
+ IN EFI_MAC_ADDRESS* SrcAddr OPTIONAL,
+ IN EFI_MAC_ADDRESS* DestAddr OPTIONAL,
+ IN UINT16* Protocol OPTIONAL
+ );
+
+/**
+ Receives a packet from a network interface.
+
+ @param This Protocol instance pointer.
+ @param HeaderSize The size, in bytes, of the media header received on the network
+ interface. If this parameter is NULL, then the media header size
+ will not be returned.
+ @param BuffSize On entry, the size, in bytes, of Buffer. On exit, the size, in
+ bytes, of the packet that was received on the network interface.
+ @param Buffer A pointer to the data buffer to receive both the media header and
+ the data.
+ @param SourceAddr The source HW MAC address. If this parameter is NULL, the
+ HW MAC source address will not be extracted from the media
+ header.
+ @param DestinationAddr The destination HW MAC address. If this parameter is NULL,
+ the HW MAC destination address will not be extracted from the
+ media header.
+ @param Protocol The media header type. If this parameter is NULL, then the
+ protocol will not be extracted from the media header. See
+ RFC 1700 section "Ether Types" for examples.
+
+ @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has
+ been updated to the number of bytes received.
+ @retval EFI_NOT_READY The network interface is too busy to accept this transmit
+ request.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_ACCESS_DENIED Error acquire global lock for operation.
+
+**/
+EFI_STATUS
+EFIAPI
+EmuSnpReceive(
+ IN EFI_SIMPLE_NETWORK_PROTOCOL* This,
+ OUT UINTN* HeaderSize OPTIONAL,
+ IN OUT UINTN* BuffSize,
+ OUT VOID* Buffer,
+ OUT EFI_MAC_ADDRESS* SourceAddr OPTIONAL,
+ OUT EFI_MAC_ADDRESS* DestinationAddr OPTIONAL,
+ OUT UINT16* Protocol OPTIONAL
+ );
+
+VOID
+EFIAPI
+EmuSnpWaitForPacketNotify(
+ IN EFI_EVENT Event,
+ IN VOID* Private
+ );
+
+#endif // _EMU_SNP_H_
diff --git a/CdeEmuPkg/EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf b/CdeEmuPkg/EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf
new file mode 100644
index 00000000000..827a0c4ad7a
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf
@@ -0,0 +1,53 @@
+#/** @file
+# Component name for module EmuSnpDxe
+#
+# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
+# Copyright (c) 2010, Apple, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EmuSnpDxe
+ FILE_GUID = 22597239-6107-DF44-AD3F-5F053E92222E
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ EDK_RELEASE_VERSION = 0x00020000
+ EFI_SPECIFICATION_VERSION = 0x00020000
+
+ ENTRY_POINT = InitializeEmuSnpDriver
+# UNLOAD_IMAGE = EmuSnpUnload
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources.common]
+ ComponentName.c
+ EmuSnpDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+ NetworkPkg/NetworkPkg.dec
+
+[LibraryClasses]
+ DevicePathLib
+ UefiLib
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ UefiDriverEntryPoint
+ NetLib
+
+[Protocols]
+ gEfiSimpleNetworkProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEmuSnpProtocolGuid
+ gEmuIoThunkProtocolGuid
+
+
diff --git a/CdeEmuPkg/EmulatorPkg/EmuThunkDxe/EmuThunk.c b/CdeEmuPkg/EmulatorPkg/EmuThunkDxe/EmuThunk.c
new file mode 100644
index 00000000000..2d30a576e6e
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuThunkDxe/EmuThunk.c
@@ -0,0 +1,83 @@
+/*++ @file
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+//
+// EmuThunk Device Path Protocol Instance
+//
+EMU_THUNK_DEVICE_PATH mEmuThunkDevicePath = {
+ {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (EMU_VENDOR_DEVICE_PATH_NODE)),
+ (UINT8) ((sizeof (EMU_VENDOR_DEVICE_PATH_NODE)) >> 8)
+ }
+ },
+ EMU_THUNK_PROTOCOL_GUID
+ },
+ 0
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+ }
+};
+
+
+EFI_STATUS
+EFIAPI
+InitializeEmuThunk (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ Install UnixThunk Protocol and it's associated Device Path protocol
+
+Arguments:
+ (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
+
+Returns:
+ EFI_SUCEESS - UnixThunk protocol is added or error status from
+ gBS->InstallMultiProtocolInterfaces().
+
+**/
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEmuThunkProtocolGuid, gEmuThunk,
+ &gEfiDevicePathProtocolGuid, &mEmuThunkDevicePath,
+ NULL
+ );
+
+ return Status;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/EmuThunkDxe/EmuThunk.inf b/CdeEmuPkg/EmulatorPkg/EmuThunkDxe/EmuThunk.inf
new file mode 100644
index 00000000000..14fdaf14607
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmuThunkDxe/EmuThunk.inf
@@ -0,0 +1,54 @@
+## @file
+# A DXE driver to produce EMU_THUNK_PROTOCOL
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EmuThunk
+ FILE_GUID = 2F62A818-4A72-CD40-90B9-FF00DAABEE7B
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeEmuThunk
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ EmuThunk.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ EmuThunkLib
+ UefiDriverEntryPoint
+ UefiLib
+ DebugLib
+ DevicePathLib
+
+
+
+[Protocols]
+ gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gEmuThunkProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+
+
+[Depex]
+ TRUE
+
diff --git a/CdeEmuPkg/EmulatorPkg/EmulatorPkg.ci.yaml b/CdeEmuPkg/EmulatorPkg/EmulatorPkg.ci.yaml
new file mode 100644
index 00000000000..e747d3c424a
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmulatorPkg.ci.yaml
@@ -0,0 +1,109 @@
+## @file
+# Core CI configuration for EmulatorPkg
+#
+# EmulatorPkg is part of Platform Ci for builds so this is only
+# used for code analysis.
+#
+# Copyright (c) Microsoft Corporation
+# Copyright (c) 2020, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+ ## options defined .pytool/Plugin/LicenseCheck
+ "LicenseCheck": {
+ "IgnoreFiles": []
+ },
+ "EccCheck": {
+ ## Exception sample looks like below:
+ ## "ExceptionList": [
+ ## "", ""
+ ## ]
+ "ExceptionList": [
+ ],
+ ## Both file path and directory path are accepted.
+ "IgnoreFiles": [
+ "EmuBlockIoDxe/EmuBlockIo.c",
+ "EmuGopDxe/GopInput.c",
+ "EmuSnpDxe/EmuSnpDxe.c",
+ "EmuSimpleFileSystemDxe/EmuSimpleFileSystem.c",
+ "FvbServicesRuntimeDxe/FWBlockService.c",
+ "Win/Host/WinFileSystem.c",
+ "Win/Host/WinInclude.h"
+ ]
+ },
+ ## options defined .pytool/Plugin/CompilerPlugin
+ "CompilerPlugin": {
+ "DscPath": "" # Don't support this test
+ },
+
+ ## options defined .pytool/Plugin/HostUnitTestCompilerPlugin
+ "HostUnitTestCompilerPlugin": {
+ "DscPath": "" # Don't support this test
+ },
+
+ ## options defined .pytool/Plugin/CharEncodingCheck
+ "CharEncodingCheck": {
+ "IgnoreFiles": []
+ },
+
+ ## options defined .pytool/Plugin/DependencyCheck
+ "DependencyCheck": {
+ "AcceptableDependencies": [
+ # For this platform all packages are allowed???
+ "MdePkg/MdePkg.dec",
+ "MdeModulePkg/MdeModulePkg.dec",
+ "EmulatorPkg/EmulatorPkg.dec",
+ "NetworkPkg/NetworkPkg.dec",
+ "RedfishPkg/RedfishPkg.dec",
+ "EmbeddedPkg/EmbeddedPkg.dec", ## is this one OK??
+ ],
+ # For host based unit tests
+ "AcceptableDependencies-HOST_APPLICATION":[
+ "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
+ ],
+ # For UEFI shell based apps
+ "AcceptableDependencies-UEFI_APPLICATION":[],
+ "IgnoreInf": []
+ },
+
+ ## options defined .pytool/Plugin/DscCompleteCheck
+ "DscCompleteCheck": {
+ "IgnoreInf": [""],
+ "DscPath": "" # Don't support this test
+ },
+
+ ## options defined .pytool/Plugin/HostUnitTestDscCompleteCheck
+ "HostUnitTestDscCompleteCheck": {
+ "IgnoreInf": [""],
+ "DscPath": "" # Don't support this test
+ },
+
+ ## options defined .pytool/Plugin/GuidCheck
+ "GuidCheck": {
+ "IgnoreGuidName": [],
+ "IgnoreGuidValue": [],
+ "IgnoreFoldersAndFiles": [],
+ "IgnoreDuplicates": [],
+ },
+
+ ## options defined .pytool/Plugin/LibraryClassCheck
+ "LibraryClassCheck": {
+ "IgnoreHeaderFile": []
+ },
+
+ ## options defined .pytool/Plugin/SpellCheck
+ "SpellCheck": {
+ "AuditOnly": True, # Fails right now with over 270 errors
+ "IgnoreFiles": [], # use gitignore syntax to ignore errors in matching files
+ "ExtendWords": [
+ "setjump",
+ "plong",
+ "lparam",
+ "lpdword",
+ "lpthread",
+ "lresult",
+ ], # words to extend to the dictionary for this package
+ "IgnoreStandardPaths": [], # Standard Plugin defined paths that should be ignore
+ "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
+ }
+}
diff --git a/CdeEmuPkg/EmulatorPkg/EmulatorPkg.dec b/CdeEmuPkg/EmulatorPkg/EmulatorPkg.dec
new file mode 100644
index 00000000000..d1e481beefb
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmulatorPkg.dec
@@ -0,0 +1,123 @@
+## @file
+#
+# This is the Emu Emulation Environment Platform
+#
+# Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. All rights reserved.
+# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = EmulatorPkg
+ PACKAGE_GUID = 36E48BD7-7D92-5A47-A2CD-513F072E3300
+ PACKAGE_VERSION = 0.1
+
+
+[Includes]
+ Include
+
+
+[LibraryClasses]
+ ThunkPpiList|Include/Library/ThunkPpiList.h
+ ThunkProtocolList|Include/Library/ThunkProtocolList.h
+ EmuThunkLib|Include/Library/EmuThunkLib.h
+ KeyMap|Include/Library/KeyMapLib.h
+ PpiListLib|Include/Library/PpiListLib.h
+ SmbiosLib|Include/Library/SmbiosLib.h
+ EmuMagicPageLib|Include/Library/EmuMagicPageLib.h
+
+[Protocols]
+ gEmuThunkProtocolGuid = { 0x5CF32E0B, 0x8EDF, 0x2E44, { 0x9C, 0xDA, 0x93, 0x20, 0x5E, 0x99, 0xEC, 0x1C } }
+ gEmuIoThunkProtocolGuid = { 0x453368F6, 0x7C85, 0x434A, { 0xA9, 0x8A, 0x72, 0xD1, 0xB7, 0xFF, 0xA9, 0x26 } }
+ gEmuGraphicsWindowProtocolGuid = { 0x30FD316A, 0x6728, 0x2E41, { 0xA6, 0x90, 0x0D, 0x13, 0x33, 0xD8, 0xCA, 0xC1 } }
+ gEmuThreadThunkProtocolGuid = { 0x3B1E4B7C, 0x09D8, 0x944F, { 0xA4, 0x08, 0x13, 0x09, 0xEB, 0x8B, 0x44, 0x27 } }
+ gEmuBlockIoProtocolGuid = { 0x6888A4AE, 0xAFCE, 0xE84B, { 0x91, 0x02, 0xF7, 0xB9, 0xDA, 0xE6, 0xA0, 0x30 } }
+ gEmuSnpProtocolGuid = { 0xFD5FBE54, 0x8C35, 0xB345, { 0x8A, 0x0F, 0x7A, 0xC8, 0xA5, 0xFD, 0x05, 0x21 } }
+
+[Ppis]
+ gEmuThunkPpiGuid = { 0xE113F896, 0x75CF, 0xF640, { 0x81, 0x7F, 0xC8, 0x5A, 0x79, 0xE8, 0xAE, 0x67 } }
+
+[Guids]
+ gEmulatorPkgTokenSpaceGuid = { 0x4F792E68, 0xE8C8, 0x794E, { 0xB1, 0xD8, 0x37, 0x03, 0xF3, 0xF2, 0xD5, 0xA5 } }
+ gEmuSystemConfigGuid = { 0xF8626165, 0x6CEB, 0x924A, { 0xBA, 0xFC, 0xF1, 0x3A, 0xB9, 0xD6, 0x57, 0x28 } }
+ gEmuVirtualDisksGuid = { 0xf2ba331a, 0x8985, 0x11db, { 0xa4, 0x06, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35 } }
+ gEmuPhysicalDisksGuid = { 0xf2bdcc96, 0x8985, 0x11db, { 0x87, 0x19, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35 } }
+ gEmuRedfishServiceGuid = { 0x3fb208ac, 0x2185, 0x498c, { 0xbf, 0x46, 0xdc, 0x23, 0xda, 0x58, 0x7b, 0x55 } }
+
+[PcdsFeatureFlag]
+ ## If TRUE, if symbols only load on breakpoints and gdb entry
+ gEmulatorPkgTokenSpaceGuid.PcdEmulatorLazyLoadSymbols|TRUE|BOOLEAN|0x00020000
+
+[PcdsFixedAtBuild]
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageVariableBase|0x0|UINT64|0x00001014
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwSpareBase|0x0|UINT64|0x00001015
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwWorkingBase|0x0|UINT64|0x00001016
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFdBaseAddress|0x0|UINT64|0x00001017
+
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogBase|0x0|UINT64|0x0000100e
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogSize|0x0|UINT32|0x0000100f
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashFvRecoveryBase|0x0|UINT64|0x00001010
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashFvRecoverySize|0x0|UINT32|0x00001011
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareFdSize|0x0|UINT32|0x00001012
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareBlockSize|0|UINT32|0x00001013
+
+ ## Number of Application Processors (APs) in the system 0 means Uniprocessor mode
+ gEmulatorPkgTokenSpaceGuid.PcdEmuApCount|L"0"|VOID*|0x00001019
+
+ ## Magic page to implement PEI Services Table Pointer Lib
+ gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage|0x1013000000|UINT64|0x0000101b
+
+ ## Size of the packet filter
+ gEmulatorPkgTokenSpaceGuid.PcdNetworkPacketFilterSize|524288|UINT32|0x0000101c
+
+ ## Platform level Redfish Service control PCD
+ # These PCDs are used to stop the Redfish sevice when secure boot is disabled
+ # or exit boot service.
+ gEmulatorPkgTokenSpaceGuid.PcdRedfishServieStopIfSecureBootDisabled|TRUE|BOOLEAN|0x00001020
+ gEmulatorPkgTokenSpaceGuid.PcdRedfishServieStopIfExitbootService|TRUE|BOOLEAN|0x00001021
+ ##
+ # edk2 Redfish implementation on Emulator package is designed to access
+ # to Redfish simulator.
+ # https://github.com/DMTF/Redfish-Profile-Simulator
+ # The user ID and password are fixed as below.
+ gEmulatorPkgTokenSpaceGuid.PcdRedfishServieUserId|"admin"|VOID*|0x00001022
+ gEmulatorPkgTokenSpaceGuid.PcdRedfishServiePassword|"pwd123456"|VOID*|0x00001023
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+ gEmulatorPkgTokenSpaceGuid.PcdEmuBootMode|1|UINT32|0x00001006
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareVolume|L"..\\Fv\\Fv_Recovery.fd"|VOID*|0x00001009
+ gEmulatorPkgTokenSpaceGuid.PcdEmuMemorySize|L"64!64"|VOID*|0x0000100c
+
+ #
+ # filename[:[R|F][O|W]][:BlockSize]
+ # filename can be a device node, like /dev/disk1
+ # R - Removable Media F - Fixed Media
+ # O - Write protected W - Writable
+ # Default is Fixed Media, Writable
+ # For a file the default BlockSize is 512, and can be overridden via BlockSize,
+ # for example 2048 for an ISO CD image. The block size for a device comes from
+ # the device and is not configurable.
+ # Device Size comes from file or device.
+ # On Mac OS X you can use Disk Utility to create .dmg files and mount them like disks
+ gEmulatorPkgTokenSpaceGuid.PcdEmuVirtualDisk|L"disk.dmg:FW"|VOID*|0x00001001
+
+ gEmulatorPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window"|VOID*|0x00001018
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFileSystem|L"."|VOID*|0x00001004
+ gEmulatorPkgTokenSpaceGuid.PcdEmuSerialPort|L"/dev/ttyS0"|VOID*|0x00001002
+
+ #
+ # On Unix host, this is the network interface name on host system that will
+ # be used in UEFI.
+ # On Win host, this is the network interface index number on Windows that
+ # will be used in UEFI. For example, string L"0" is the first network
+ # interface.
+ gEmulatorPkgTokenSpaceGuid.PcdEmuNetworkInterface|L"en0"|VOID*|0x0000100d
+
+ gEmulatorPkgTokenSpaceGuid.PcdEmuCpuModel|L"Intel(R) Processor Model"|VOID*|0x00001007
+ gEmulatorPkgTokenSpaceGuid.PcdEmuCpuSpeed|L"3000"|VOID*|0x00001008
+ gEmulatorPkgTokenSpaceGuid.PcdEmuMpServicesPollingInterval|0x100|UINT64|0x0000101a
+
diff --git a/CdeEmuPkg/EmulatorPkg/EmulatorPkg.dsc b/CdeEmuPkg/EmulatorPkg/EmulatorPkg.dsc
new file mode 100644
index 00000000000..7cbc1929f76
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmulatorPkg.dsc
@@ -0,0 +1,505 @@
+## @file
+# UEFI/PI Emulation Platform with UEFI HII interface supported.
+#
+# The Emulation Platform can be used to debug individual modules, prior to creating
+# a real platform. This also provides an example for how an DSC is created.
+#
+# Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.
+# Copyright (c) Microsoft Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ PLATFORM_NAME = EmulatorPkg
+ PLATFORM_GUID = 05FD064D-1073-E844-936C-A0E16317107D
+ PLATFORM_VERSION = 0.3
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/Emulator$(ARCH)
+
+ SUPPORTED_ARCHITECTURES = X64|IA32
+ BUILD_TARGETS = DEBUG|RELEASE|NOOPT
+ SKUID_IDENTIFIER = DEFAULT
+ FLASH_DEFINITION = EmulatorPkg/EmulatorPkg.fdf
+
+
+ #
+ # Network definition
+ #
+ DEFINE NETWORK_SNP_ENABLE = FALSE
+ DEFINE NETWORK_IP6_ENABLE = FALSE
+ DEFINE NETWORK_TLS_ENABLE = FALSE
+ DEFINE NETWORK_HTTP_BOOT_ENABLE = FALSE
+ DEFINE NETWORK_HTTP_ENABLE = FALSE
+ DEFINE NETWORK_ISCSI_ENABLE = FALSE
+ DEFINE SECURE_BOOT_ENABLE = FALSE
+
+ #
+ # Redfish definition
+ #
+ DEFINE REDFISH_ENABLE = FALSE
+
+[SkuIds]
+ 0|DEFAULT
+
+!include MdePkg/MdeLibs.dsc.inc
+
+[LibraryClasses]
+ #
+ # Entry point
+ #
+ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+ DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+ #
+ # Basic
+ #
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
+
+ #
+ # UEFI & PI
+ #
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+ UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+ SmbiosLib|EmulatorPkg/Library/SmbiosLib/SmbiosLib.inf
+
+ #
+ # Generic Modules
+ #
+ UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+ BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+ UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+ BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
+ SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+ CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+ SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+ SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
+ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+ #
+ # Platform
+ #
+ PlatformBootManagerLib|EmulatorPkg/Library/PlatformBmLib/PlatformBmLib.inf
+ KeyMapLib|EmulatorPkg/Library/KeyMapLibNull/KeyMapLibNull.inf
+ !if $(REDFISH_ENABLE) == TRUE
+ RedfishPlatformHostInterfaceLib|EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.inf
+ RedfishPlatformCredentialLib|EmulatorPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCredentialLib.inf
+ !endif
+ #
+ # Misc
+ #
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+ DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+ PeiServicesTablePointerLib|EmulatorPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointerLibMagicPage.inf
+ DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
+ LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+ CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
+ TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+ VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+ VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
+ VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+ SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf
+ ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
+ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+ PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf
+ AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+ SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf
+ SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf
+!else
+ AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+!endif
+
+[LibraryClasses.common.SEC]
+ PeiServicesLib|EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ PeCoffGetEntryPointLib|EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf
+ PeCoffExtraActionLib|EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf
+ SerialPortLib|EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
+ PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+ TimerLib|EmulatorPkg/Library/PeiTimerLib/PeiTimerLib.inf
+
+[LibraryClasses.common.USER_DEFINED, LibraryClasses.common.BASE]
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf
+ ThunkPpiList|EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf
+ ThunkProtocolList|EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+ PpiListLib|EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf
+ PeiServicesLib|EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf
+
+
+[LibraryClasses.common.PEIM, LibraryClasses.common.PEI_CORE]
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+ PeCoffGetEntryPointLib|EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf
+ PeCoffExtraActionLib|EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+ SerialPortLib|EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+ TimerLib|EmulatorPkg/Library/PeiTimerLib/PeiTimerLib.inf
+
+[LibraryClasses.common.PEI_CORE]
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+[LibraryClasses.common.PEIM]
+ PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+ HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+ MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+ PeCoffExtraActionLib|EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ TimerLib|EmulatorPkg/Library/DxeCoreTimerLib/DxeCoreTimerLib.inf
+ EmuThunkLib|EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.inf
+
+[LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.UEFI_APPLICATION]
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+!endif
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.UEFI_DRIVER, LibraryClasses.common.DXE_DRIVER, LibraryClasses.common.UEFI_APPLICATION]
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+ EmuThunkLib|EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.inf
+ PeCoffExtraActionLib|EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+ TimerLib|EmulatorPkg/Library/DxeTimerLib/DxeTimerLib.inf
+
+[PcdsFeatureFlag]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst|FALSE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplBuildPageTables|FALSE
+
+[PcdsFixedAtBuild]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x00000000
+ gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000040
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x0f
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizeNonPopulateCapsule|0x0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxSizePopulateCapsule|0x0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE
+
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareFdSize|0x002a0000
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareBlockSize|0x10000
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareVolume|L"../FV/FV_RECOVERY.fd"
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+ gEfiSecurityPkgTokenSpaceGuid.PcdUserPhysicalPresence|TRUE
+!endif
+
+ gEmulatorPkgTokenSpaceGuid.PcdEmuMemorySize|L"64!64"
+
+ # Change PcdBootManagerMenuFile to UiApp
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+
+#define BOOT_WITH_FULL_CONFIGURATION 0x00
+#define BOOT_WITH_MINIMAL_CONFIGURATION 0x01
+#define BOOT_ASSUMING_NO_CONFIGURATION_CHANGES 0x02
+#define BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS 0x03
+#define BOOT_WITH_DEFAULT_SETTINGS 0x04
+#define BOOT_ON_S4_RESUME 0x05
+#define BOOT_ON_S5_RESUME 0x06
+#define BOOT_ON_S2_RESUME 0x10
+#define BOOT_ON_S3_RESUME 0x11
+#define BOOT_ON_FLASH_UPDATE 0x12
+#define BOOT_IN_RECOVERY_MODE 0x20
+ gEmulatorPkgTokenSpaceGuid.PcdEmuBootMode|0
+
+ gEmulatorPkgTokenSpaceGuid.PcdEmuApCount|L"1"
+
+ # For a CD-ROM/DVD use L"diag.dmg:RO:2048"
+ gEmulatorPkgTokenSpaceGuid.PcdEmuVirtualDisk|L"disk.dmg:FW"
+ gEmulatorPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window"
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFileSystem|L"."
+ gEmulatorPkgTokenSpaceGuid.PcdEmuSerialPort|L"/dev/ttyS0"
+ gEmulatorPkgTokenSpaceGuid.PcdEmuNetworkInterface|L"en0"
+
+ gEmulatorPkgTokenSpaceGuid.PcdEmuCpuModel|L"Intel(R) Processor Model"
+ gEmulatorPkgTokenSpaceGuid.PcdEmuCpuSpeed|L"3000"
+
+ # 0-PCANSI, 1-VT100, 2-VT00+, 3-UTF8, 4-TTYTERM
+ gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|1
+
+!if $(REDFISH_ENABLE) == TRUE
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceDevicePath.DevicePathMatchMode|DEVICE_PATH_MATCH_MAC_NODE
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceDevicePath.DevicePathNum|1
+ #
+ # Below is the MAC address of network adapter on EDK2 Emulator platform.
+ # You can use ifconfig under EFI shell to get the MAC address of network adapter on EDK2 Emulator platform.
+ #
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceDevicePath.DevicePath|{DEVICE_PATH("MAC(000000000000,0x1)")}
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceAccessModeInBand|False
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDiscoverAccessModeInBand|False
+!endif
+
+[PcdsDynamicDefault.common.DEFAULT]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
+
+[PcdsDynamicHii.common.DEFAULT]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|L"Setup"|gEmuSystemConfigGuid|0x0|80
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|L"Setup"|gEmuSystemConfigGuid|0x4|25
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|10
+
+[Components]
+!if "IA32" in $(ARCH) || "X64" in $(ARCH)
+ !if "MSFT" in $(FAMILY) || $(WIN_HOST_BUILD) == TRUE
+ ##
+ # Emulator, OS WIN application
+ # CLANGPDB is cross OS tool chain. It depends on WIN_HOST_BUILD flag
+ # to build WinHost application.
+ ##
+ EmulatorPkg/Win/Host/WinHost.inf
+ !else
+ ##
+ # Emulator, OS POSIX application
+ ##
+ EmulatorPkg/Unix/Host/Host.inf
+ !endif
+!endif
+
+!ifndef $(SKIP_MAIN_BUILD)
+ #
+ # Generic SEC
+ #
+ EmulatorPkg/Sec/Sec.inf
+
+ ##
+ # PEI Phase modules
+ ##
+ MdeModulePkg/Core/Pei/PeiMain.inf
+ MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+ MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+ MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+
+ EmulatorPkg/BootModePei/BootModePei.inf
+ MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+ MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+ EmulatorPkg/AutoScanPei/AutoScanPei.inf
+ EmulatorPkg/FirmwareVolumePei/FirmwareVolumePei.inf
+ EmulatorPkg/FlashMapPei/FlashMapPei.inf
+ EmulatorPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf
+ MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+ ##
+ # DXE Phase modules
+ ##
+ MdeModulePkg/Core/Dxe/DxeMain.inf {
+
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+ SerialPortLib|EmulatorPkg/Library/DxeEmuStdErrSerialPortLib/DxeEmuStdErrSerialPortLib.inf
+ DxeEmuLib|EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.inf
+ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+ NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ }
+ MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+
+ MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+ MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf {
+
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+ SerialPortLib|EmulatorPkg/Library/DxeEmuStdErrSerialPortLib/DxeEmuStdErrSerialPortLib.inf
+ }
+
+ MdeModulePkg/Universal/Metronome/Metronome.inf
+ EmulatorPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf
+ EmulatorPkg/ResetRuntimeDxe/Reset.inf
+ MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ EmulatorPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+
+ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+!endif
+ }
+
+ MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+ MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+ EmulatorPkg/EmuThunkDxe/EmuThunk.inf
+ EmulatorPkg/CpuRuntimeDxe/Cpu.inf
+ MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+ EmulatorPkg/PlatformSmbiosDxe/PlatformSmbiosDxe.inf
+ EmulatorPkg/TimerDxe/Timer.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+ SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+
+ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+
+ NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+ }
+ MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+ MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+ MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ MdeModulePkg/Universal/SerialDxe/SerialDxe.inf {
+
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ SerialPortLib|EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf
+ }
+
+ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+!if "XCODE5" not in $(TOOL_CHAIN_TAG)
+ MdeModulePkg/Logo/LogoDxe.inf
+!endif
+ MdeModulePkg/Universal/LoadFileOnFv2/LoadFileOnFv2.inf
+ MdeModulePkg/Application/UiApp/UiApp.inf {
+
+ NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+ NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+ NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+ }
+ MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
+
+ MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ #{
+ #
+ # NULL|EmulatorPkg/Library/DevicePathTextLib/DevicePathTextLib.inf
+ #}
+
+ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+ MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+ MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+ EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf
+ EmulatorPkg/EmuGopDxe/EmuGopDxe.inf
+ EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf
+ EmulatorPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf
+ EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf
+
+ MdeModulePkg/Application/HelloWorld/HelloWorld.inf
+
+ MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+ MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+ MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+ MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+ MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+ MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf {
+
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+
+ FatPkg/EnhancedFatDxe/Fat.inf
+
+!if "XCODE5" not in $(TOOL_CHAIN_TAG)
+ ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf {
+
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ }
+!endif
+ ShellPkg/Application/Shell/Shell.inf {
+
+ ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+ 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/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+ NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+ HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+ OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+ SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+# SafeBlockIoLib|ShellPkg/Library/SafeBlockIoLib/SafeBlockIoLib.inf
+# SafeOpenProtocolLib|ShellPkg/Library/SafeOpenProtocolLib/SafeOpenProtocolLib.inf
+ BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+
+
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+ gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+ gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+ }
+
+!endif
+
+!include NetworkPkg/Network.dsc.inc
+
+!if $(REDFISH_ENABLE) == TRUE
+ EmulatorPkg/Application/RedfishPlatformConfig/RedfishPlatformConfig.inf
+!endif
+!include RedfishPkg/Redfish.dsc.inc
+
+[BuildOptions]
+ #
+ # Disable deprecated APIs.
+ #
+ *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
+
+ MSFT:DEBUG_*_*_CC_FLAGS = /Od /Oy-
+ MSFT:NOOPT_*_*_CC_FLAGS = /Od /Oy-
+ GCC:DEBUG_CLANGPDB_*_CC_FLAGS =-O0 -Wno-unused-command-line-argument -Wno-incompatible-pointer-types -Wno-enum-conversion -Wno-incompatible-pointer-types -Wno-sometimes-uninitialized -Wno-constant-conversion -Wno-main-return-type
+
+ MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096 /FILEALIGN:4096 /SUBSYSTEM:CONSOLE
+ MSFT:DEBUG_*_*_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /BASE:0x10000
+ MSFT:NOOPT_*_*_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /BASE:0x10000
+
+!if $(WIN_HOST_BUILD) == TRUE
+ #
+ # CLANGPDB tool chain depends on WIN_HOST_BUILD flag to generate the windows application.
+ #
+ GCC:*_CLANGPDB_*_DLINK_FLAGS = /ALIGN:4096 /FILEALIGN:4096 /SUBSYSTEM:CONSOLE
+ GCC:DEBUG_CLANGPDB_*_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /BASE:0x10000
+ GCC:NOOPT_CLANGPDB_*_DLINK_FLAGS = /EXPORT:InitializeDriver=$(IMAGE_ENTRY_POINT) /BASE:0x10000
+!endif
diff --git a/CdeEmuPkg/EmulatorPkg/EmulatorPkg.fdf b/CdeEmuPkg/EmulatorPkg/EmulatorPkg.fdf
new file mode 100644
index 00000000000..d8cc9d823f5
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/EmulatorPkg.fdf
@@ -0,0 +1,323 @@
+## @file
+# This is Emulator FDF file with UEFI HII features enabled
+#
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2009 - 2011, Apple Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+[FD.Fv_Recovery]
+#
+# In OS X PEIMs are really XIP, so we need to make this address match the malloced
+# buffer for the FD (0x41000000). If this address does not match the FV will get
+# relocated in place (works, but not a great idea).
+#
+BaseAddress = 0x102000000|gEmulatorPkgTokenSpaceGuid.PcdEmuFdBaseAddress #The base address of the FLASH Device.
+Size = 0x005a0000|gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareFdSize #The size in bytes of the FLASH Device
+ErasePolarity = 1
+BlockSize = 0x10000
+NumBlocks = 0x5a
+
+0x00000000|0x00580000
+gEmulatorPkgTokenSpaceGuid.PcdEmuFlashFvRecoveryBase|gEmulatorPkgTokenSpaceGuid.PcdEmuFlashFvRecoverySize
+FV = FvRecovery
+
+0x00580000|0x0000c000
+gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageVariableBase|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: 0x20000
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ # Signature "_FVH" #Attributes
+ 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+ # HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+ 0x48, 0x00, 0x36, 0x09, 0x00, 0x00, 0x00, 0x02,
+ # Blockmap[0]: 2 Blocks * 0x10000 Bytes / Block
+ 0x02, 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) == FALSE
+ #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,
+!else
+ # 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,
+!endif
+ #Size: 0xc000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0xBFB8
+ # This can speed up the Variable Dispatch a bit.
+ 0xB8, 0xBF, 0x00, 0x00,
+ #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+ 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x0058c000|0x00002000
+#NV_EVENT_LOG
+gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogBase|gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogSize
+
+0x0058e000|0x00002000
+gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwWorkingBase|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
+}
+
+0x00590000|0x00010000
+#NV_FTW_SPARE
+gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+[FV.FvRecovery]
+FvNameGuid = 6D99E806-3D38-42c2-A095-5F4300BFD7DC
+FvAlignment = 16 #FV alignment and FV attributes setting.
+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
+
+#
+# PEI Phase modules
+#
+
+#
+# PEI Apriori file example, more PEIM module added later.
+#
+APRIORI PEI {
+ INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+ INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+ INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+ }
+APRIORI DXE {
+ INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+ INF MdeModulePkg/Universal/Metronome/Metronome.inf
+ }
+INF EmulatorPkg/Sec/Sec.inf
+INF MdeModulePkg/Core/Pei/PeiMain.inf
+INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+INF EmulatorPkg/BootModePei/BootModePei.inf
+INF EmulatorPkg/AutoScanPei/AutoScanPei.inf
+INF EmulatorPkg/FirmwareVolumePei/FirmwareVolumePei.inf
+INF EmulatorPkg/FlashMapPei/FlashMapPei.inf
+INF EmulatorPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf
+INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
+INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+#
+# DXE Phase modules
+#
+INF MdeModulePkg/Core/Dxe/DxeMain.inf
+INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+INF MdeModulePkg/Universal/Metronome/Metronome.inf
+INF EmulatorPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf
+INF EmulatorPkg/ResetRuntimeDxe/Reset.inf
+INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+INF EmulatorPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+INF MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+INF EmulatorPkg/EmuThunkDxe/EmuThunk.inf
+INF EmulatorPkg/CpuRuntimeDxe/Cpu.inf
+INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+INF EmulatorPkg/PlatformSmbiosDxe/PlatformSmbiosDxe.inf
+INF EmulatorPkg/TimerDxe/Timer.inf
+INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+
+INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+
+INF EmulatorPkg/EmuBusDriverDxe/EmuBusDriverDxe.inf
+INF EmulatorPkg/EmuGopDxe/EmuGopDxe.inf
+INF EmulatorPkg/EmuSimpleFileSystemDxe/EmuSimpleFileSystemDxe.inf
+INF EmulatorPkg/EmuBlockIoDxe/EmuBlockIoDxe.inf
+INF EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf
+
+INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+INF MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+!if "XCODE5" not in $(TOOL_CHAIN_TAG)
+INF MdeModulePkg/Logo/LogoDxe.inf
+!endif
+INF MdeModulePkg/Universal/LoadFileOnFv2/LoadFileOnFv2.inf
+INF RuleOverride = UI MdeModulePkg/Application/UiApp/UiApp.inf
+INF MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
+INF MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf
+
+#
+# Secure Boot Key Enroll
+#
+!if $(SECURE_BOOT_ENABLE) == TRUE
+INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+
+#
+# Network stack drivers
+#
+!if $(NETWORK_SUPPORT)
+INF EmulatorPkg/EmuSnpDxe/EmuSnpDxe.inf
+!endif
+!include NetworkPkg/Network.fdf.inc
+
+#
+# EFI Redfish drivers
+#
+!include RedfishPkg/Redfish.fdf.inc
+
+INF FatPkg/EnhancedFatDxe/Fat.inf
+
+!if "XCODE5" not in $(TOOL_CHAIN_TAG)
+INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
+!endif
+INF ShellPkg/Application/Shell/Shell.inf
+
+[Rule.Common.SEC]
+ FILE SEC = $(NAMED_GUID) {
+ PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING ="$(MODULE_NAME)" Optional
+ VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+
+[Rule.Common.PEI_CORE]
+ FILE PEI_CORE = $(NAMED_GUID) {
+ PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING ="$(MODULE_NAME)" Optional
+ VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.PEIM]
+ FILE PEIM = $(NAMED_GUID) {
+ PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 Align=Auto $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.DXE_CORE]
+ FILE DXE_CORE = $(NAMED_GUID) {
+ COMPRESS PI_STD {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+ }
+
+[Rule.Common.UEFI_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ COMPRESS PI_STD {
+ GUIDED {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+ }
+ }
+
+[Rule.Common.DXE_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ COMPRESS PI_STD {
+ GUIDED {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+ }
+ }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ COMPRESS PI_STD {
+ GUIDED {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+ }
+ }
+
+[Rule.Common.UEFI_APPLICATION]
+ FILE APPLICATION = $(NAMED_GUID) {
+ COMPRESS PI_STD {
+ GUIDED {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+ }
+ }
+
+[Rule.Common.UEFI_APPLICATION.UI]
+ FILE APPLICATION = $(NAMED_GUID) {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="Enter Setup"
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional |.depex
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+ FILE APPLICATION = $(NAMED_GUID) {
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
diff --git a/CdeEmuPkg/EmulatorPkg/FirmwareVolumePei/FirmwareVolumePei.c b/CdeEmuPkg/EmulatorPkg/FirmwareVolumePei/FirmwareVolumePei.c
new file mode 100644
index 00000000000..43c7fa69c45
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/FirmwareVolumePei/FirmwareVolumePei.c
@@ -0,0 +1,124 @@
+/*++ @file
+
+Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiPei.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+EFI_STATUS
+EFIAPI
+PeimInitializeFirmwareVolumePei (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+ Perform a call-back into the SEC simulator to get address of the Firmware Hub
+
+Arguments:
+ FfsHeader - Ffs Header available to every PEIM
+ PeiServices - General purpose services available to every PEIM.
+
+Returns:
+ None
+
+**/
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
+ EMU_THUNK_PPI *Thunk;
+ EFI_PHYSICAL_ADDRESS FdBase;
+ EFI_PHYSICAL_ADDRESS FdFixUp;
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ UINT64 FdSize;
+ UINTN Index;
+
+ DEBUG ((EFI_D_ERROR, "Unix Firmware Volume PEIM Loaded\n"));
+
+ //
+ // Get the Fwh Information PPI
+ //
+ Status = PeiServicesLocatePpi (
+ &gEmuThunkPpiGuid, // GUID
+ 0, // INSTANCE
+ &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR
+ (VOID **)&Thunk // PPI
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Index = 0;
+ do {
+ //
+ // Get information about all the FD's in the system
+ //
+ Status = Thunk->FirmwareDevices (Index, &FdBase, &FdSize, &FdFixUp);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Assume the FD starts with an FV header
+ //
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FdBase;
+
+ //
+ // Make an FV Hob for the first FV in the FD
+ //
+ BuildFvHob (FdBase, FvHeader->FvLength);
+
+ if (Index == 0) {
+ //
+ // Assume the first FD was produced by the NT32.DSC
+ // All these strange offests are needed to keep in
+ // sync with the FlashMap and NT32.dsc file
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_FIRMWARE_DEVICE,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ FdBase,
+ (
+ FvHeader->FvLength +
+ PcdGet32 (PcdFlashNvStorageVariableSize) +
+ PcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+ PcdGet32 (PcdFlashNvStorageFtwSpareSize) +
+ PcdGet32 (PcdEmuFlashNvStorageEventLogSize)
+ )
+ );
+
+ //
+ // Hard code the address of the spare block and variable services.
+ // Assume it's a hard coded offset from FV0 in FD0.
+ //
+ FdSize =
+ PcdGet32 (PcdFlashNvStorageVariableSize) +
+ PcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+ PcdGet32 (PcdFlashNvStorageFtwSpareSize) +
+ PcdGet32 (PcdEmuFlashNvStorageEventLogSize);
+
+ BuildFvHob (FdFixUp + PcdGet64 (PcdEmuFlashNvStorageVariableBase), FdSize);
+ } else {
+ //
+ // For other FD's just map them in.
+ //
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_FIRMWARE_DEVICE,
+ (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE),
+ FdBase,
+ FdSize
+ );
+ }
+ }
+
+ Index++;
+ } while (!EFI_ERROR (Status));
+
+ return Status;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/FirmwareVolumePei/FirmwareVolumePei.inf b/CdeEmuPkg/EmulatorPkg/FirmwareVolumePei/FirmwareVolumePei.inf
new file mode 100644
index 00000000000..ffe63953854
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/FirmwareVolumePei/FirmwareVolumePei.inf
@@ -0,0 +1,55 @@
+## @file
+# Component description file for EmuFwh module
+#
+# This PEIM will produce the HOB to describe Firmware Volume, Firmware Devices
+# on the Emu emulator.
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FirmwareVolumePei
+ FILE_GUID = 6DB075DE-449E-2644-96D0-CC5A1B4C3B2A
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PeimInitializeFirmwareVolumePei
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ FirmwareVolumePei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+[LibraryClasses]
+ PeiServicesTablePointerLib
+ PeiServicesLib
+ HobLib
+ PeimEntryPoint
+ DebugLib
+
+[Pcd]
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogSize
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageVariableBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+
+[Ppis]
+ gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED
+
+[Depex]
+ gEmuThunkPpiGuid AND gEfiPeiMemoryDiscoveredPpiGuid
+
diff --git a/CdeEmuPkg/EmulatorPkg/FlashMapPei/FlashMapPei.c b/CdeEmuPkg/EmulatorPkg/FlashMapPei/FlashMapPei.c
new file mode 100644
index 00000000000..bc287bead65
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/FlashMapPei/FlashMapPei.c
@@ -0,0 +1,77 @@
+/*++ @file
+ PEIM to build GUIDed HOBs for platform specific flash map
+
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "PiPei.h"
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+EFI_STATUS
+EFIAPI
+PeimInitializeFlashMap (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+ Build GUIDed HOBs for platform specific flash map
+
+Arguments:
+ FfsHeader - A pointer to the EFI_FFS_FILE_HEADER structure.
+ PeiServices - General purpose services available to every PEIM.
+
+Returns:
+ EFI_STATUS
+
+**/
+{
+ EFI_STATUS Status;
+ EMU_THUNK_PPI *Thunk;
+ EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
+ EFI_PHYSICAL_ADDRESS FdBase;
+ EFI_PHYSICAL_ADDRESS FdFixUp;
+ UINT64 FdSize;
+
+ DEBUG ((EFI_D_ERROR, "EmulatorPkg Flash Map PEIM Loaded\n"));
+
+ //
+ // Get the Fwh Information PPI
+ //
+ Status = PeiServicesLocatePpi (
+ &gEmuThunkPpiGuid, // GUID
+ 0, // INSTANCE
+ &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR
+ (VOID **)&Thunk // PPI
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Assume that FD0 contains the Flash map.
+ //
+ Status = Thunk->FirmwareDevices (0, &FdBase, &FdSize, &FdFixUp);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ PcdSet64S (PcdFlashNvStorageVariableBase64, PcdGet64 (PcdEmuFlashNvStorageVariableBase) + FdFixUp);
+ PcdSet64S (PcdFlashNvStorageFtwWorkingBase64, PcdGet64 (PcdEmuFlashNvStorageFtwWorkingBase) + FdFixUp);
+ PcdSet64S (PcdFlashNvStorageFtwSpareBase64, PcdGet64 (PcdEmuFlashNvStorageFtwSpareBase) + FdFixUp);
+
+ return EFI_SUCCESS;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/FlashMapPei/FlashMapPei.inf b/CdeEmuPkg/EmulatorPkg/FlashMapPei/FlashMapPei.inf
new file mode 100644
index 00000000000..bb2f414771f
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/FlashMapPei/FlashMapPei.inf
@@ -0,0 +1,63 @@
+## @file
+# Component description file for FlashMap PEI module
+#
+# This module installs FlashMap PPI which is used to get flash layout information.
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FlashMapPei
+ FILE_GUID = C9FAF091-57F8-A64C-A07A-445B124F0D93
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = PeimInitializeFlashMap
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ FlashMapPei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+[LibraryClasses]
+ PcdLib
+ BaseMemoryLib
+ PeiServicesTablePointerLib
+ PeiServicesLib
+ HobLib
+ PeimEntryPoint
+ DebugLib
+
+
+[Ppis]
+ gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
+
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwWorkingBase
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwSpareBase
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageVariableBase
+
+[Depex]
+ gEmuThunkPpiGuid
+
diff --git a/CdeEmuPkg/EmulatorPkg/FvbServicesRuntimeDxe/FWBlockService.c b/CdeEmuPkg/EmulatorPkg/FvbServicesRuntimeDxe/FWBlockService.c
new file mode 100644
index 00000000000..d92ec9e3dd0
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/FvbServicesRuntimeDxe/FWBlockService.c
@@ -0,0 +1,1350 @@
+/*++ @file
+
+Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PiDxe.h"
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "FwBlockService.h"
+
+ESAL_FWB_GLOBAL *mFvbModuleGlobal;
+
+#define EFI_FVB2_STATUS (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_STATUS)
+
+EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = {
+ FVB_DEVICE_SIGNATURE,
+ {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ {
+ sizeof (MEMMAP_DEVICE_PATH),
+ 0
+ }
+ },
+ EfiMemoryMappedIO,
+ 0,
+ 0,
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ 0
+ }
+ }
+ },
+ 0,
+ {
+ FvbProtocolGetAttributes,
+ FvbProtocolSetAttributes,
+ FvbProtocolGetPhysicalAddress,
+ FvbProtocolGetBlockSize,
+ FvbProtocolRead,
+ FvbProtocolWrite,
+ FvbProtocolEraseBlocks,
+ NULL
+ }
+};
+
+
+
+VOID
+EFIAPI
+FvbVirtualddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ Fixup internal data so that EFI and SAL can be call in virtual mode.
+ Call the passed in Child Notify event and convert the mFvbModuleGlobal
+ date items to there virtual address.
+
+ mFvbModuleGlobal->FvInstance[FVB_PHYSICAL] - Physical copy of instance data
+ mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] - Virtual pointer to common
+ instance data.
+
+Arguments:
+
+ (Standard EFI notify event - EFI_EVENT_NOTIFY)
+
+Returns:
+
+ None
+
+**/
+{
+ EFI_FW_VOL_INSTANCE *FwhInstance;
+ UINTN Index;
+
+ EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvInstance[FVB_VIRTUAL]);
+
+ //
+ // Convert the base address of all the instances
+ //
+ Index = 0;
+ FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];
+ while (Index < mFvbModuleGlobal->NumFv) {
+ EfiConvertPointer (0x0, (VOID **) &FwhInstance->FvBase[FVB_VIRTUAL]);
+ FwhInstance = (EFI_FW_VOL_INSTANCE *)
+ (
+ (UINTN) ((UINT8 *) FwhInstance) + FwhInstance->VolumeHeader.HeaderLength +
+ (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+ );
+ Index++;
+ }
+
+ EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal);
+}
+
+EFI_STATUS
+GetFvbInstance (
+ IN UINTN Instance,
+ IN ESAL_FWB_GLOBAL *Global,
+ OUT EFI_FW_VOL_INSTANCE **FwhInstance,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Retrieves the physical address of a memory mapped FV
+
+Arguments:
+ Instance - The FV instance whose base address is going to be
+ returned
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ FwhInstance - The EFI_FW_VOL_INSTANCE fimrware instance structure
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_INVALID_PARAMETER - Instance not found
+
+**/
+{
+ EFI_FW_VOL_INSTANCE *FwhRecord;
+
+ if (Instance >= Global->NumFv) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Find the right instance of the FVB private data
+ //
+ FwhRecord = Global->FvInstance[Virtual];
+ while (Instance > 0) {
+ FwhRecord = (EFI_FW_VOL_INSTANCE *)
+ (
+ (UINTN) ((UINT8 *) FwhRecord) + FwhRecord->VolumeHeader.HeaderLength +
+ (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+ );
+ Instance--;
+ }
+
+ *FwhInstance = FwhRecord;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetPhysicalAddress (
+ IN UINTN Instance,
+ OUT EFI_PHYSICAL_ADDRESS *Address,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Retrieves the physical address of a memory mapped FV
+
+Arguments:
+ Instance - The FV instance whose base address is going to be
+ returned
+ Address - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS
+ that on successful return, contains the base address
+ of the firmware volume.
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_INVALID_PARAMETER - Instance not found
+
+**/
+{
+ EFI_FW_VOL_INSTANCE *FwhInstance = NULL;
+ EFI_STATUS Status;
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+ *Address = FwhInstance->FvBase[Virtual];
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetVolumeAttributes (
+ IN UINTN Instance,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Retrieves attributes, insures positive polarity of attribute bits, returns
+ resulting attributes in output parameter
+
+Arguments:
+ Instance - The FV instance whose attributes is going to be
+ returned
+ Attributes - Output buffer which contains attributes
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_INVALID_PARAMETER - Instance not found
+
+**/
+{
+ EFI_FW_VOL_INSTANCE *FwhInstance = NULL;
+ EFI_STATUS Status;
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+ *Attributes = FwhInstance->VolumeHeader.Attributes;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbGetLbaAddress (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ OUT UINTN *LbaAddress,
+ OUT UINTN *LbaLength,
+ OUT UINTN *NumOfBlocks,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Retrieves the starting address of an LBA in an FV
+
+Arguments:
+ Instance - The FV instance which the Lba belongs to
+ Lba - The logical block address
+ LbaAddress - On output, contains the physical starting address
+ of the Lba
+ LbaLength - On output, contains the length of the block
+ NumOfBlocks - A pointer to a caller allocated UINTN in which the
+ number of consecutive blocks starting with Lba is
+ returned. All blocks in this range have a size of
+ BlockSize
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_INVALID_PARAMETER - Instance not found
+
+**/
+{
+ UINT32 NumBlocks;
+ UINT32 BlockLength;
+ UINTN Offset;
+ EFI_LBA StartLba;
+ EFI_LBA NextLba;
+ EFI_FW_VOL_INSTANCE *FwhInstance = NULL;
+ EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
+ EFI_STATUS Status;
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+
+ StartLba = 0;
+ Offset = 0;
+ BlockMap = &(FwhInstance->VolumeHeader.BlockMap[0]);
+
+ //
+ // Parse the blockmap of the FV to find which map entry the Lba belongs to
+ //
+ while (TRUE) {
+ NumBlocks = BlockMap->NumBlocks;
+ BlockLength = BlockMap->Length;
+
+ if (NumBlocks == 0 || BlockLength == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ NextLba = StartLba + NumBlocks;
+
+ //
+ // The map entry found
+ //
+ if (Lba >= StartLba && Lba < NextLba) {
+ Offset = Offset + (UINTN) MultU64x32 ((Lba - StartLba), BlockLength);
+ if (LbaAddress != NULL) {
+ *LbaAddress = FwhInstance->FvBase[Virtual] + Offset;
+ }
+
+ if (LbaLength != NULL) {
+ *LbaLength = BlockLength;
+ }
+
+ if (NumOfBlocks != NULL) {
+ *NumOfBlocks = (UINTN) (NextLba - Lba);
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ StartLba = NextLba;
+ Offset = Offset + NumBlocks * BlockLength;
+ BlockMap++;
+ }
+}
+
+EFI_STATUS
+FvbReadBlock (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ IN UINTN BlockOffset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Reads specified number of bytes into a buffer from the specified block
+
+Arguments:
+ Instance - The FV instance to be read from
+ Lba - The logical block address to be read from
+ BlockOffset - Offset into the block at which to begin reading
+ NumBytes - Pointer that on input contains the total size of
+ the buffer. On output, it contains the total number
+ of bytes read
+ Buffer - Pointer to a caller allocated buffer that will be
+ used to hold the data read
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - The firmware volume was read successfully and
+ contents are in Buffer
+ EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output,
+ NumBytes contains the total number of bytes returned
+ in Buffer
+ EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be read
+ EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL
+
+**/
+{
+ EFI_FVB_ATTRIBUTES_2 Attributes;
+ UINTN LbaAddress;
+ UINTN LbaLength;
+ EFI_STATUS Status;
+
+ //
+ // Check for invalid conditions
+ //
+ if ((NumBytes == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*NumBytes == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Check if the FV is read enabled
+ //
+ FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);
+
+ if ((Attributes & EFI_FVB2_READ_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ //
+ // Perform boundary checks and adjust NumBytes
+ //
+ if (BlockOffset > LbaLength) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (LbaLength < (*NumBytes + BlockOffset)) {
+ *NumBytes = (UINT32) (LbaLength - BlockOffset);
+ Status = EFI_BAD_BUFFER_SIZE;
+ }
+
+ CopyMem (Buffer, (UINT8 *) (LbaAddress + BlockOffset), (UINTN) (*NumBytes));
+
+ return Status;
+}
+
+EFI_STATUS
+FvbWriteBlock (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ IN UINTN BlockOffset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Writes specified number of bytes from the input buffer to the block
+
+Arguments:
+ Instance - The FV instance to be written to
+ Lba - The starting logical block index to write to
+ BlockOffset - Offset into the block at which to begin writing
+ NumBytes - Pointer that on input contains the total size of
+ the buffer. On output, it contains the total number
+ of bytes actually written
+ Buffer - Pointer to a caller allocated buffer that contains
+ the source for the write
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - The firmware volume was written successfully
+ EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On output,
+ NumBytes contains the total number of bytes
+ actually written
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be written
+ EFI_INVALID_PARAMETER - Instance not found, or NumBytes, Buffer are NULL
+
+**/
+{
+ EFI_FVB_ATTRIBUTES_2 Attributes;
+ UINTN LbaAddress;
+ UINTN LbaLength;
+ EFI_STATUS Status;
+
+ //
+ // Check for invalid conditions
+ //
+ if ((NumBytes == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*NumBytes == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Check if the FV is write enabled
+ //
+ FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);
+
+ if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ //
+ // Perform boundary checks and adjust NumBytes
+ //
+ if (BlockOffset > LbaLength) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (LbaLength < (*NumBytes + BlockOffset)) {
+ *NumBytes = (UINT32) (LbaLength - BlockOffset);
+ Status = EFI_BAD_BUFFER_SIZE;
+ }
+ //
+ // Write data
+ //
+ CopyMem ((UINT8 *) (LbaAddress + BlockOffset), Buffer, (UINTN) (*NumBytes));
+
+ return Status;
+}
+
+EFI_STATUS
+FvbEraseBlock (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Erases and initializes a firmware volume block
+
+Arguments:
+ Instance - The FV instance to be erased
+ Lba - The logical block index to be erased
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - The erase request was successfully completed
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be written. Firmware device may have been
+ partially erased
+ EFI_INVALID_PARAMETER - Instance not found
+
+**/
+{
+
+ EFI_FVB_ATTRIBUTES_2 Attributes;
+ UINTN LbaAddress;
+ UINTN LbaLength;
+ EFI_STATUS Status;
+ UINT8 Data;
+
+ //
+ // Check if the FV is write enabled
+ //
+ FvbGetVolumeAttributes (Instance, &Attributes, Global, Virtual);
+
+ if ((Attributes & EFI_FVB2_WRITE_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ //
+ // Get the starting address of the block for erase.
+ //
+ Status = FvbGetLbaAddress (Instance, Lba, &LbaAddress, &LbaLength, NULL, Global, Virtual);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if ((Attributes & EFI_FVB2_ERASE_POLARITY) != 0) {
+ Data = 0xFF;
+ } else {
+ Data = 0x0;
+ }
+
+ SetMem ((UINT8 *) LbaAddress, LbaLength, Data);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+FvbSetVolumeAttributes (
+ IN UINTN Instance,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+/*++
+
+Routine Description:
+ Modifies the current settings of the firmware volume according to the
+ input parameter, and returns the new setting of the volume
+
+Arguments:
+ Instance - The FV instance whose attributes is going to be
+ modified
+ Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES_2
+ containing the desired firmware volume settings.
+ On successful return, it contains the new settings
+ of the firmware volume
+ Global - Pointer to ESAL_FWB_GLOBAL that contains all
+ instance data
+ Virtual - Whether CPU is in virtual or physical mode
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+ EFI_ACCESS_DENIED - The volume setting is locked and cannot be modified
+ EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are
+ in conflict with the capabilities as declared in the
+ firmware volume header
+
+**/
+{
+ EFI_FW_VOL_INSTANCE *FwhInstance = NULL;
+ EFI_FVB_ATTRIBUTES_2 OldAttributes;
+ EFI_FVB_ATTRIBUTES_2 *AttribPtr;
+ UINT32 Capabilities;
+ UINT32 OldStatus;
+ UINT32 NewStatus;
+ EFI_STATUS Status;
+ EFI_FVB_ATTRIBUTES_2 UnchangedAttributes;
+
+
+ //
+ // Find the right instance of the FVB private data
+ //
+ Status = GetFvbInstance (Instance, Global, &FwhInstance, Virtual);
+ ASSERT_EFI_ERROR (Status);
+
+ AttribPtr = (EFI_FVB_ATTRIBUTES_2 *) &(FwhInstance->VolumeHeader.Attributes);
+ OldAttributes = *AttribPtr;
+ Capabilities = OldAttributes & (EFI_FVB2_READ_DISABLED_CAP | \
+ EFI_FVB2_READ_ENABLED_CAP | \
+ EFI_FVB2_WRITE_DISABLED_CAP | \
+ EFI_FVB2_WRITE_ENABLED_CAP | \
+ EFI_FVB2_LOCK_CAP \
+ );
+
+ OldStatus = OldAttributes & EFI_FVB2_STATUS;
+ NewStatus = *Attributes & EFI_FVB2_STATUS;
+ UnchangedAttributes = EFI_FVB2_READ_DISABLED_CAP | \
+ EFI_FVB2_READ_ENABLED_CAP | \
+ EFI_FVB2_WRITE_DISABLED_CAP | \
+ EFI_FVB2_WRITE_ENABLED_CAP | \
+ EFI_FVB2_LOCK_CAP | \
+ EFI_FVB2_STICKY_WRITE | \
+ EFI_FVB2_MEMORY_MAPPED | \
+ EFI_FVB2_ERASE_POLARITY | \
+ EFI_FVB2_READ_LOCK_CAP | \
+ EFI_FVB2_WRITE_LOCK_CAP | \
+ EFI_FVB2_ALIGNMENT;
+
+ //
+ // Some attributes of FV is read only can *not* be set
+ //
+ if ((OldAttributes & UnchangedAttributes) ^ (*Attributes & UnchangedAttributes)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If firmware volume is locked, no status bit can be updated
+ //
+ if (OldAttributes & EFI_FVB2_LOCK_STATUS) {
+ if (OldStatus ^ NewStatus) {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+ //
+ // Test read disable
+ //
+ if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) == 0) {
+ if ((NewStatus & EFI_FVB2_READ_STATUS) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Test read enable
+ //
+ if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) == 0) {
+ if (NewStatus & EFI_FVB2_READ_STATUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Test write disable
+ //
+ if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) == 0) {
+ if ((NewStatus & EFI_FVB2_WRITE_STATUS) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Test write enable
+ //
+ if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) == 0) {
+ if (NewStatus & EFI_FVB2_WRITE_STATUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Test lock
+ //
+ if ((Capabilities & EFI_FVB2_LOCK_CAP) == 0) {
+ if (NewStatus & EFI_FVB2_LOCK_STATUS) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ *AttribPtr = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS));
+ *AttribPtr = (*AttribPtr) | NewStatus;
+ *Attributes = *AttribPtr;
+
+ return EFI_SUCCESS;
+}
+//
+// FVB protocol APIs
+//
+EFI_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ )
+/*++
+
+Routine Description:
+
+ Retrieves the physical address of the device.
+
+Arguments:
+
+ This - Calling context
+ Address - Output buffer containing the address.
+
+Returns:
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+
+**/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbGetPhysicalAddress (FvbDevice->Instance, Address, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetBlockSize (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumOfBlocks
+ )
+/*++
+
+Routine Description:
+ Retrieve the size of a logical block
+
+Arguments:
+ This - Calling context
+ Lba - Indicates which block to return the size for.
+ BlockSize - A pointer to a caller allocated UINTN in which
+ the size of the block is returned
+ NumOfBlocks - a pointer to a caller allocated UINTN in which the
+ number of consecutive blocks starting with Lba is
+ returned. All blocks in this range have a size of
+ BlockSize
+
+Returns:
+ EFI_SUCCESS - The firmware volume was read successfully and
+ contents are in Buffer
+
+**/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbGetLbaAddress (
+ FvbDevice->Instance,
+ Lba,
+ NULL,
+ BlockSize,
+ NumOfBlocks,
+ mFvbModuleGlobal,
+ EfiGoneVirtual ()
+ );
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+/*++
+
+Routine Description:
+ Retrieves Volume attributes. No polarity translations are done.
+
+Arguments:
+ This - Calling context
+ Attributes - output buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+
+**/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+/*++
+
+Routine Description:
+ Sets Volume attributes. No polarity translations are done.
+
+Arguments:
+ This - Calling context
+ Attributes - output buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - Successfully returns
+
+**/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ The EraseBlock() function erases one or more blocks as denoted by the
+ variable argument list. The entire parameter list of blocks must be verified
+ prior to erasing any blocks. If a block is requested that does not exist
+ within the associated firmware volume (it has a larger index than the last
+ block of the firmware volume), the EraseBlock() function must return
+ EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.
+
+Arguments:
+ This - Calling context
+ ... - Starting LBA followed by Number of Lba to erase.
+ a -1 to terminate the list.
+
+Returns:
+ EFI_SUCCESS - The erase request was successfully completed
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be written. Firmware device may have been
+ partially erased
+
+**/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+ EFI_FW_VOL_INSTANCE *FwhInstance = NULL;
+ UINTN NumOfBlocks;
+ VA_LIST args;
+ EFI_LBA StartingLba;
+ UINTN NumOfLba;
+ EFI_STATUS Status;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ Status = GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal, &FwhInstance, EfiGoneVirtual ());
+ ASSERT_EFI_ERROR (Status);
+
+ NumOfBlocks = FwhInstance->NumOfBlocks;
+
+ VA_START (args, This);
+
+ do {
+ StartingLba = VA_ARG (args, EFI_LBA);
+ if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
+ break;
+ }
+
+ NumOfLba = VA_ARG (args, UINTN);
+
+ //
+ // Check input parameters
+ //
+ if (NumOfLba == 0 || (StartingLba + NumOfLba) > NumOfBlocks) {
+ VA_END (args);
+ return EFI_INVALID_PARAMETER;
+ }
+ } while (1);
+
+ VA_END (args);
+
+ VA_START (args, This);
+ do {
+ StartingLba = VA_ARG (args, EFI_LBA);
+ if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
+ break;
+ }
+
+ NumOfLba = VA_ARG (args, UINTN);
+
+ while (NumOfLba > 0) {
+ Status = FvbEraseBlock (FvbDevice->Instance, StartingLba, mFvbModuleGlobal, EfiGoneVirtual ());
+ if (EFI_ERROR (Status)) {
+ VA_END (args);
+ return Status;
+ }
+
+ StartingLba++;
+ NumOfLba--;
+ }
+
+ } while (1);
+
+ VA_END (args);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolWrite (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Writes data beginning at Lba:Offset from FV. The write terminates either
+ when *NumBytes of data have been written, or when a block boundary is
+ reached. *NumBytes is updated to reflect the actual number of bytes
+ written. The write opertion does not include erase. This routine will
+ attempt to write only the specified bytes. If the writes do not stick,
+ it will return an error.
+
+Arguments:
+ This - Calling context
+ Lba - Block in which to begin write
+ Offset - Offset in the block at which to begin write
+ NumBytes - On input, indicates the requested write size. On
+ output, indicates the actual number of bytes written
+ Buffer - Buffer containing source data for the write.
+
+Returns:
+ EFI_SUCCESS - The firmware volume was written successfully
+ EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On output,
+ NumBytes contains the total number of bytes
+ actually written
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be written
+ EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL
+
+**/
+{
+
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbWriteBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+
+EFI_STATUS
+EFIAPI
+FvbProtocolRead (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Reads data beginning at Lba:Offset from FV. The Read terminates either
+ when *NumBytes of data have been read, or when a block boundary is
+ reached. *NumBytes is updated to reflect the actual number of bytes
+ written. The write opertion does not include erase. This routine will
+ attempt to write only the specified bytes. If the writes do not stick,
+ it will return an error.
+
+Arguments:
+ This - Calling context
+ Lba - Block in which to begin Read
+ Offset - Offset in the block at which to begin Read
+ NumBytes - On input, indicates the requested write size. On
+ output, indicates the actual number of bytes Read
+ Buffer - Buffer containing source data for the Read.
+
+Returns:
+ EFI_SUCCESS - The firmware volume was read successfully and
+ contents are in Buffer
+ EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output,
+ NumBytes contains the total number of bytes returned
+ in Buffer
+ EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and
+ could not be read
+ EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL
+
+**/
+{
+
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ return FvbReadBlock (FvbDevice->Instance, Lba, Offset, NumBytes, Buffer, mFvbModuleGlobal, EfiGoneVirtual ());
+}
+EFI_STATUS
+ValidateFvHeader (
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader
+ )
+/*++
+
+Routine Description:
+ Check the integrity of firmware volume header
+
+Arguments:
+ FwVolHeader - A pointer to a firmware volume header
+
+Returns:
+ EFI_SUCCESS - The firmware volume is consistent
+ EFI_NOT_FOUND - The firmware volume has corrupted. So it is not an FV
+
+**/
+{
+ UINT16 *Ptr;
+ UINT16 HeaderLength;
+ UINT16 Checksum;
+
+ //
+ // Verify the header revision, header signature, length
+ // Length of FvBlock cannot be 2**64-1
+ // HeaderLength cannot be an odd number
+ //
+ if ((FwVolHeader->Revision != EFI_FVH_REVISION) ||
+ (FwVolHeader->Signature != EFI_FVH_SIGNATURE) ||
+ (FwVolHeader->FvLength == ((UINTN) -1)) ||
+ ((FwVolHeader->HeaderLength & 0x01) != 0)
+ ) {
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Verify the header checksum
+ //
+ HeaderLength = (UINT16) (FwVolHeader->HeaderLength / 2);
+ Ptr = (UINT16 *) FwVolHeader;
+ Checksum = 0;
+ while (HeaderLength > 0) {
+ Checksum = Checksum + (*Ptr);
+ HeaderLength--;
+ Ptr++;
+ }
+
+ if (Checksum != 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FvbInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ This function does common initialization for FVB services
+
+Arguments:
+
+Returns:
+
+**/
+{
+ EFI_STATUS Status;
+ EFI_FW_VOL_INSTANCE *FwhInstance = NULL;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ EFI_DXE_SERVICES *DxeServices;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
+ UINT32 BufferSize;
+ EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;
+ EFI_HANDLE FwbHandle;
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface;
+ EFI_DEVICE_PATH_PROTOCOL *TempFwbDevicePath;
+ FV_DEVICE_PATH TempFvbDevicePathData;
+ UINT32 MaxLbaSize;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 Length;
+ UINTN NumOfBlocks;
+ EFI_PEI_HOB_POINTERS FvHob;
+
+ //
+ // Get the DXE services table
+ //
+ DxeServices = gDS;
+
+ //
+ // Allocate runtime services data for global variable, which contains
+ // the private data of all firmware volume block instances
+ //
+ Status = gBS->AllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (ESAL_FWB_GLOBAL),
+ (VOID**) &mFvbModuleGlobal
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Calculate the total size for all firmware volume block instances
+ //
+ BufferSize = 0;
+
+ FvHob.Raw = GetHobList ();
+ while ((FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw)) != NULL) {
+ BaseAddress = FvHob.FirmwareVolume->BaseAddress;
+ Length = FvHob.FirmwareVolume->Length;
+ //
+ // Check if it is a "real" flash
+ //
+ Status = DxeServices->GetMemorySpaceDescriptor (
+ BaseAddress,
+ &Descriptor
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {
+ FvHob.Raw = GET_NEXT_HOB (FvHob);
+ continue;
+ }
+
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;
+ Status = ValidateFvHeader (FwVolHeader);
+ if (EFI_ERROR (Status)) {
+ //
+ // Get FvbInfo
+ //
+ Status = GetFvbInfo (Length, &FwVolHeader);
+ if (EFI_ERROR (Status)) {
+ FvHob.Raw = GET_NEXT_HOB (FvHob);
+ continue;
+ }
+ }
+
+ BufferSize += (sizeof (EFI_FW_VOL_INSTANCE) + FwVolHeader->HeaderLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER));
+ FvHob.Raw = GET_NEXT_HOB (FvHob);
+ }
+
+ //
+ // Only need to allocate once. There is only one copy of physical memory for
+ // the private data of each FV instance. But in virtual mode or in physical
+ // mode, the address of the the physical memory may be different.
+ //
+ Status = gBS->AllocatePool (
+ EfiRuntimeServicesData,
+ BufferSize,
+ (VOID**) &mFvbModuleGlobal->FvInstance[FVB_PHYSICAL]
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Make a virtual copy of the FvInstance pointer.
+ //
+ FwhInstance = mFvbModuleGlobal->FvInstance[FVB_PHYSICAL];
+ mFvbModuleGlobal->FvInstance[FVB_VIRTUAL] = FwhInstance;
+
+ mFvbModuleGlobal->NumFv = 0;
+ MaxLbaSize = 0;
+
+ FvHob.Raw = GetHobList ();
+ while (NULL != (FvHob.Raw = GetNextHob (EFI_HOB_TYPE_FV, FvHob.Raw))) {
+ BaseAddress = FvHob.FirmwareVolume->BaseAddress;
+ Length = FvHob.FirmwareVolume->Length;
+ //
+ // Check if it is a "real" flash
+ //
+ Status = DxeServices->GetMemorySpaceDescriptor (
+ BaseAddress,
+ &Descriptor
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (Descriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {
+ FvHob.Raw = GET_NEXT_HOB (FvHob);
+ continue;
+ }
+
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress;
+ Status = ValidateFvHeader (FwVolHeader);
+ if (EFI_ERROR (Status)) {
+ //
+ // Get FvbInfo to provide in FwhInstance.
+ //
+ Status = GetFvbInfo (Length, &FwVolHeader);
+ if (EFI_ERROR (Status)) {
+ FvHob.Raw = GET_NEXT_HOB (FvHob);
+ continue;
+ }
+ //
+ // Write healthy FV header back.
+ //
+ CopyMem (
+ (VOID *) (UINTN) BaseAddress,
+ (VOID *) FwVolHeader,
+ FwVolHeader->HeaderLength
+ );
+ }
+
+ FwhInstance->FvBase[FVB_PHYSICAL] = (UINTN) BaseAddress;
+ FwhInstance->FvBase[FVB_VIRTUAL] = (UINTN) BaseAddress;
+
+ CopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader, FwVolHeader->HeaderLength);
+ FwVolHeader = &(FwhInstance->VolumeHeader);
+ EfiInitializeLock (&(FwhInstance->FvbDevLock), TPL_HIGH_LEVEL);
+
+ NumOfBlocks = 0;
+
+ for (PtrBlockMapEntry = FwVolHeader->BlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {
+ //
+ // Get the maximum size of a block. The size will be used to allocate
+ // buffer for Scratch space, the intermediate buffer for FVB extension
+ // protocol
+ //
+ if (MaxLbaSize < PtrBlockMapEntry->Length) {
+ MaxLbaSize = PtrBlockMapEntry->Length;
+ }
+
+ NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks;
+ }
+ //
+ // The total number of blocks in the FV.
+ //
+ FwhInstance->NumOfBlocks = NumOfBlocks;
+
+ //
+ // Add a FVB Protocol Instance
+ //
+ Status = gBS->AllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (EFI_FW_VOL_BLOCK_DEVICE),
+ (VOID**) &FvbDevice
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ CopyMem (FvbDevice, &mFvbDeviceTemplate, sizeof (EFI_FW_VOL_BLOCK_DEVICE));
+
+ FvbDevice->Instance = mFvbModuleGlobal->NumFv;
+ mFvbModuleGlobal->NumFv++;
+
+ //
+ // Set up the devicepath
+ //
+ FvbDevice->DevicePath.MemMapDevPath.StartingAddress = BaseAddress;
+ FvbDevice->DevicePath.MemMapDevPath.EndingAddress = BaseAddress + (FwVolHeader->FvLength - 1);
+
+ //
+ // Find a handle with a matching device path that has supports FW Block protocol
+ //
+ TempFwbDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) &TempFvbDevicePathData;
+ CopyMem (TempFwbDevicePath, &FvbDevice->DevicePath, sizeof (FV_DEVICE_PATH));
+ Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &TempFwbDevicePath, &FwbHandle);
+ if (EFI_ERROR (Status)) {
+ //
+ // LocateDevicePath fails so install a new interface and device path
+ //
+ FwbHandle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &FwbHandle,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ &FvbDevice->FwVolBlockInstance,
+ &gEfiDevicePathProtocolGuid,
+ &FvbDevice->DevicePath,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else if (IsDevicePathEnd (TempFwbDevicePath)) {
+ //
+ // Device allready exists, so reinstall the FVB protocol
+ //
+ Status = gBS->HandleProtocol (
+ FwbHandle,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ (VOID**)&OldFwbInterface
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->ReinstallProtocolInterface (
+ FwbHandle,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ OldFwbInterface,
+ &FvbDevice->FwVolBlockInstance
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ } else {
+ //
+ // There was a FVB protocol on an End Device Path node
+ //
+ ASSERT (FALSE);
+ }
+
+ FwhInstance = (EFI_FW_VOL_INSTANCE *)
+ (
+ (UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength +
+ (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))
+ );
+
+ FvHob.Raw = GET_NEXT_HOB (FvHob);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/FvbServicesRuntimeDxe/FvbInfo.c b/CdeEmuPkg/EmulatorPkg/FvbServicesRuntimeDxe/FvbInfo.c
new file mode 100644
index 00000000000..8c0099f42eb
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/FvbServicesRuntimeDxe/FvbInfo.c
@@ -0,0 +1,148 @@
+/*++ @file
+ Defines data structure that is the volume header found.These data is intent
+ to decouple FVB driver with FV header.
+
+Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+typedef struct {
+ UINT64 FvLength;
+ EFI_FIRMWARE_VOLUME_HEADER FvbInfo;
+ //
+ // EFI_FV_BLOCK_MAP_ENTRY ExtraBlockMap[n];//n=0
+ //
+ EFI_FV_BLOCK_MAP_ENTRY End[1];
+} EFI_FVB_MEDIA_INFO;
+
+EFI_FVB_MEDIA_INFO mPlatformFvbMediaInfo[] = {
+ //
+ // Recovery BOIS FVB
+ //
+ {
+ FixedPcdGet32 (PcdEmuFlashFvRecoverySize),
+ {
+ {
+ 0,
+ }, // ZeroVector[16]
+ EFI_FIRMWARE_FILE_SYSTEM2_GUID,
+ FixedPcdGet32 (PcdEmuFlashFvRecoverySize),
+ EFI_FVH_SIGNATURE,
+ EFI_FVB2_READ_ENABLED_CAP |
+ EFI_FVB2_READ_STATUS |
+ EFI_FVB2_WRITE_ENABLED_CAP |
+ EFI_FVB2_WRITE_STATUS |
+ EFI_FVB2_ERASE_POLARITY,
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+ 0, // CheckSum
+ 0, // ExtHeaderOffset
+ {
+ 0,
+ }, // Reserved[1]
+ 2, // Revision
+ {
+ {
+ FixedPcdGet32 (PcdEmuFlashFvRecoverySize)/FixedPcdGet32 (PcdEmuFirmwareBlockSize),
+ FixedPcdGet32 (PcdEmuFirmwareBlockSize),
+ }
+ }
+ },
+ {
+ {
+ 0,
+ 0
+ }
+ }
+ },
+ //
+ // Systen NvStorage FVB
+ //
+ {
+ FixedPcdGet32 (PcdFlashNvStorageVariableSize) + \
+ FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + \
+ FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) + \
+ FixedPcdGet32 (PcdEmuFlashNvStorageEventLogSize),
+ {
+ {
+ 0,
+ }, // ZeroVector[16]
+ EFI_SYSTEM_NV_DATA_FV_GUID,
+ FixedPcdGet32 (PcdFlashNvStorageVariableSize) + \
+ FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + \
+ FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) + \
+ FixedPcdGet32 (PcdEmuFlashNvStorageEventLogSize),
+ EFI_FVH_SIGNATURE,
+ EFI_FVB2_READ_ENABLED_CAP |
+ EFI_FVB2_READ_STATUS |
+ EFI_FVB2_WRITE_ENABLED_CAP |
+ EFI_FVB2_WRITE_STATUS |
+ EFI_FVB2_ERASE_POLARITY,
+ sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY),
+ 0, // CheckSum
+ 0, // ExtHeaderOffset
+ {
+ 0,
+ }, // Reserved[1]
+ 2, // Revision
+ {
+ {
+ (FixedPcdGet32 (PcdFlashNvStorageVariableSize) + \
+ FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + \
+ FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize) + \
+ FixedPcdGet32 (PcdEmuFlashNvStorageEventLogSize)) / FixedPcdGet32 (PcdEmuFirmwareBlockSize),
+ FixedPcdGet32 (PcdEmuFirmwareBlockSize),
+ }
+ }
+ },
+ {
+ {
+ 0,
+ 0
+ }
+ }
+ }
+};
+
+EFI_STATUS
+GetFvbInfo (
+ IN UINT64 FvLength,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO); Index += 1) {
+ if (mPlatformFvbMediaInfo[Index].FvLength == FvLength) {
+ *FvbInfo = &mPlatformFvbMediaInfo[Index].FvbInfo;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf b/CdeEmuPkg/EmulatorPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
new file mode 100644
index 00000000000..6e1caa9c005
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/FvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
@@ -0,0 +1,75 @@
+## @file
+# Component description file for Emu Fimware Volume Block DXE driver module.
+#
+# This DXE runtime driver implements and produces the Fimware Volue Block Protocol on
+# Emu emulator.
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2011, Apple Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FwBlockService
+ FILE_GUID = A01E498C-96E8-2A4C-95F4-85248F989753
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = FvbInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ FvbInfo.c
+ FWBlockService.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ HobLib
+ DebugLib
+ UefiRuntimeLib
+ DxeServicesTableLib
+ BaseLib
+ UefiDriverEntryPoint
+ UefiLib
+ DevicePathLib
+
+[Guids]
+ gEfiEventVirtualAddressChangeGuid # ALWAYS_CONSUMED Create Event: EVENT_GROUP_GUID
+
+[Protocols]
+ gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gEfiDevicePathProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
+
+[FixedPcd]
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareFdSize
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareBlockSize
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashFvRecoveryBase
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashFvRecoverySize
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogBase
+ gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogSize
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+
+[Depex]
+ TRUE
+
diff --git a/CdeEmuPkg/EmulatorPkg/FvbServicesRuntimeDxe/FwBlockService.h b/CdeEmuPkg/EmulatorPkg/FvbServicesRuntimeDxe/FwBlockService.h
new file mode 100644
index 00000000000..ed6b98fead2
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/FvbServicesRuntimeDxe/FwBlockService.h
@@ -0,0 +1,213 @@
+/*++ @file
+ Firmware volume block driver for Intel Firmware Hub (FWH) device
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _FW_BLOCK_SERVICE_H
+#define _FW_BLOCK_SERVICE_H
+
+//
+// BugBug: Add documentation here for data structure!!!!
+//
+#define FVB_PHYSICAL 0
+#define FVB_VIRTUAL 1
+
+typedef struct {
+ EFI_LOCK FvbDevLock;
+ UINTN FvBase[2];
+ UINTN NumOfBlocks;
+ EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;
+} EFI_FW_VOL_INSTANCE;
+
+typedef struct {
+ UINT32 NumFv;
+ EFI_FW_VOL_INSTANCE *FvInstance[2];
+} ESAL_FWB_GLOBAL;
+
+//
+// Fvb Protocol instance data
+//
+#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)
+#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, FvbExtension, FVB_DEVICE_SIGNATURE)
+#define FVB_DEVICE_SIGNATURE SIGNATURE_32 ('F', 'V', 'B', 'N')
+
+typedef struct {
+ MEMMAP_DEVICE_PATH MemMapDevPath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevPath;
+} FV_DEVICE_PATH;
+
+typedef struct {
+ UINTN Signature;
+ FV_DEVICE_PATH DevicePath;
+ UINTN Instance;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance;
+} EFI_FW_VOL_BLOCK_DEVICE;
+
+EFI_STATUS
+GetFvbInfo (
+ IN UINT64 FvLength,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo
+ )
+;
+
+EFI_STATUS
+FvbReadBlock (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ IN UINTN BlockOffset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+;
+
+EFI_STATUS
+FvbWriteBlock (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ IN UINTN BlockOffset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+;
+
+EFI_STATUS
+FvbEraseBlock (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+;
+
+EFI_STATUS
+FvbSetVolumeAttributes (
+ IN UINTN Instance,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+;
+
+EFI_STATUS
+FvbGetVolumeAttributes (
+ IN UINTN Instance,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+;
+
+EFI_STATUS
+FvbGetPhysicalAddress (
+ IN UINTN Instance,
+ OUT EFI_PHYSICAL_ADDRESS *Address,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+;
+
+EFI_STATUS
+EFIAPI
+FvbInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+;
+
+
+VOID
+EFIAPI
+FvbClassAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+;
+
+EFI_STATUS
+FvbGetLbaAddress (
+ IN UINTN Instance,
+ IN EFI_LBA Lba,
+ OUT UINTN *LbaAddress,
+ OUT UINTN *LbaLength,
+ OUT UINTN *NumOfBlocks,
+ IN ESAL_FWB_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+;
+
+//
+// Protocol APIs
+//
+EFI_STATUS
+EFIAPI
+FvbProtocolGetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+;
+
+EFI_STATUS
+EFIAPI
+FvbProtocolSetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+;
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetPhysicalAddress (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ )
+;
+
+EFI_STATUS
+EFIAPI
+FvbProtocolGetBlockSize (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumOfBlocks
+ )
+;
+
+EFI_STATUS
+EFIAPI
+FvbProtocolRead (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+;
+
+EFI_STATUS
+EFIAPI
+FvbProtocolWrite (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+;
+
+EFI_STATUS
+EFIAPI
+FvbProtocolEraseBlocks (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ ...
+ )
+;
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Guid/EmuPhysicalDisk.h b/CdeEmuPkg/EmulatorPkg/Include/Guid/EmuPhysicalDisk.h
new file mode 100644
index 00000000000..032da6f00dc
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Guid/EmuPhysicalDisk.h
@@ -0,0 +1,18 @@
+/** @file
+ Setup Variable data structure for Emu platform.
+
+Copyright (c) 2009, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef __EMU_PHYSICAL_DISK_H__
+#define __EMU_PHYSICAL_DISK_H__
+
+#define EFI_EMU_PHYSICAL_DISK_GUID \
+ { 0xf2ba331a, 0x8985, 0x11db, { 0xa4, 0x06, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35 } }
+
+extern EFI_GUID gEmuPhysicalDisksGuid;
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Guid/EmuSystemConfig.h b/CdeEmuPkg/EmulatorPkg/Include/Guid/EmuSystemConfig.h
new file mode 100644
index 00000000000..6e0ca538850
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Guid/EmuSystemConfig.h
@@ -0,0 +1,30 @@
+/** @file
+ Setup Variable data structure for Emu platform.
+
+Copyright (c) 2009, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef __EMU_SYSTEM_CONFIG_H__
+#define __EMU_SYSTEM_CONFIG_H__
+
+#define EFI_EMU_SYSTEM_CONFIG_GUID \
+ { 0x9C4FB516, 0x3A1E, 0xD847, { 0xA1, 0xA1, 0x70, 0x58, 0xB6, 0x98, 0x67, 0x32 } }
+
+
+#pragma pack(1)
+typedef struct {
+ //
+ // Console output mode
+ //
+ UINT32 ConOutColumn;
+ UINT32 ConOutRow;
+} EMU_SYSTEM_CONFIGURATION;
+#pragma pack()
+
+
+extern EFI_GUID gEmuSystemConfigGuid;
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Guid/EmuVirtualDisk.h b/CdeEmuPkg/EmulatorPkg/Include/Guid/EmuVirtualDisk.h
new file mode 100644
index 00000000000..f3e1d091923
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Guid/EmuVirtualDisk.h
@@ -0,0 +1,18 @@
+/** @file
+ Setup Variable data structure for Emu platform.
+
+Copyright (c) 2009, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+
+**/
+
+#ifndef __EMU_VIRTUAL_DISK_H__
+#define __EMU_VIRTUAL_DISK_H__
+
+#define EFI_EMU_VIRTUAL_DISK_GUID \
+ { 0xf2ba331a, 0x8985, 0x11db, { 0xa4, 0x06, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35 } }
+
+extern EFI_GUID gEmuVirtualDisksGuid;
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Library/EmuMagicPageLib.h b/CdeEmuPkg/EmulatorPkg/Include/Library/EmuMagicPageLib.h
new file mode 100644
index 00000000000..c834adef411
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Library/EmuMagicPageLib.h
@@ -0,0 +1,32 @@
+/*++ @file
+The PCD, gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage, points to a magic page
+of memory that is like SRAM on an embedded system. This file defines what goes
+where in the magic page.
+
+Copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EMU_MAGIC_PAGE_LIB_H__
+#define __EMU_MAGIC_PAGE_LIB_H__
+
+#include
+#include
+#include
+
+typedef struct {
+ // Used by PEI Core and PEIMs to store the PEI Services pointer.
+ // Privilege issues prevent using the PI mechanism in the emulator.
+ CONST EFI_PEI_SERVICES **PeiServicesTablePointer;
+
+ // Used by SecPeiServicesLib
+ EFI_PEI_PPI_DESCRIPTOR *PpiList;
+
+ // Needed by PEI PEI PeCoffLoaderExtraActionLib
+ EMU_THUNK_PROTOCOL *Thunk;
+} EMU_MAGIC_PAGE_LAYOUT;
+
+#define EMU_MAGIC_PAGE() ((EMU_MAGIC_PAGE_LAYOUT *)((UINTN)PcdGet64 (PcdPeiServicesTablePage)))
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Library/EmuThunkLib.h b/CdeEmuPkg/EmulatorPkg/Include/Library/EmuThunkLib.h
new file mode 100644
index 00000000000..9f838363a85
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Library/EmuThunkLib.h
@@ -0,0 +1,36 @@
+/*++ @file
+
+Copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EMU_THUNK_LIB_H__
+#define __EMU_THUNK_LIB_H__
+
+#include
+
+
+extern EMU_THUNK_PROTOCOL *gEmuThunk;
+
+
+/**
+ Serach the EMU IO Thunk database for a matching EMU IO Thunk
+ Protocol instance.
+
+ @param Protocol Protocol to search for.
+ @param Instance Instance of protocol to search for.
+
+ @retval NULL Protocol and Instance not found.
+ @retval other EMU IO Thunk protocol that matched.
+
+**/
+EMU_IO_THUNK_PROTOCOL *
+EFIAPI
+GetIoThunkInstance (
+ IN EFI_GUID *Protocol,
+ IN UINTN Instance
+ );
+
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Library/KeyMapLib.h b/CdeEmuPkg/EmulatorPkg/Include/Library/KeyMapLib.h
new file mode 100644
index 00000000000..6f3db7c56bb
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Library/KeyMapLib.h
@@ -0,0 +1,37 @@
+/*++ @file
+
+Copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include
+
+
+/**
+ KeyMapMake gets called on key presses.
+
+ @param KeyData Key that was pressed.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+KeyMapMake (
+ IN EFI_KEY_DATA *KeyData
+ );
+
+/**
+ KeyMapBreak gets called on key releases.
+
+ @param KeyData Key that was pressed.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+KeyMapBreak (
+ IN EFI_KEY_DATA *KeyData
+ );
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Library/PpiListLib.h b/CdeEmuPkg/EmulatorPkg/Include/Library/PpiListLib.h
new file mode 100644
index 00000000000..4cdb39a05cb
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Library/PpiListLib.h
@@ -0,0 +1,15 @@
+/*++ @file
+
+Copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __PPI_LIST_LIB_H__
+#define __PPI_LIST_LIB_H__
+
+
+extern CONST EFI_PEI_PPI_DESCRIPTOR *gPpiList;
+
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Library/SmbiosLib.h b/CdeEmuPkg/EmulatorPkg/Include/Library/SmbiosLib.h
new file mode 100644
index 00000000000..fce7352cb82
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Library/SmbiosLib.h
@@ -0,0 +1,196 @@
+/** @file
+ Provides library functions for common SMBIOS operations. Only available to DXE
+ and UEFI module types.
+
+
+Copyright (c) 2012, Apple Inc. All rights reserved.
+Portitions Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SMBIOS_LIB_H__
+#define _SMBIOS_LIB_H__
+
+#include
+#include
+
+
+///
+/// Cache copy of the SMBIOS Protocol pointer
+///
+extern EFI_SMBIOS_PROTOCOL *gSmbios;
+
+
+///
+/// Template for SMBIOS table initialization.
+/// The SMBIOS_TABLE_STRING types in the formated area must match the
+/// StringArray sequene.
+///
+typedef struct {
+ //
+ // formatted area of a given SMBIOS record
+ //
+ SMBIOS_STRUCTURE *Entry;
+ //
+ // NULL terminated array of ASCII strings to be added to the SMBIOS record.
+ //
+ CHAR8 **StringArray;
+} SMBIOS_TEMPLATE_ENTRY;
+
+
+/**
+ Create an initial SMBIOS Table from an array of SMBIOS_TEMPLATE_ENTRY
+ entries. SMBIOS_TEMPLATE_ENTRY.NULL indicates the end of the table.
+
+ @param Template Array of SMBIOS_TEMPLATE_ENTRY entries.
+
+ @retval EFI_SUCCESS New SMBIOS tables were created.
+ @retval EFI_OUT_OF_RESOURCES New SMBIOS tables were not created.
+**/
+EFI_STATUS
+EFIAPI
+SmbiosLibInitializeFromTemplate (
+ IN SMBIOS_TEMPLATE_ENTRY *Template
+ );
+
+
+
+/**
+ Create SMBIOS record.
+
+ Converts a fixed SMBIOS structure and an array of pointers to strings into
+ an SMBIOS record where the strings are cat'ed on the end of the fixed record
+ and terminated via a double NULL and add to SMBIOS table.
+
+ SMBIOS_TABLE_TYPE32 gSmbiosType12 = {
+ { EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS, sizeof (SMBIOS_TABLE_TYPE12), 0 },
+ 1 // StringCount
+ };
+ CHAR8 *gSmbiosType12Strings[] = {
+ "Not Found",
+ NULL
+ };
+
+ ...
+ AddSmbiosEntryFromTemplate (
+ (EFI_SMBIOS_TABLE_HEADER*)&gSmbiosType12,
+ gSmbiosType12Strings
+ );
+
+ @param SmbiosEntry Fixed SMBIOS structure
+ @param StringArray Array of strings to convert to an SMBIOS string pack.
+ NULL is OK.
+
+ @retval EFI_SUCCESS New SmbiosEntry was added to SMBIOS table.
+ @retval EFI_OUT_OF_RESOURCES SmbiosEntry was not added.
+**/
+EFI_STATUS
+EFIAPI
+SmbiosLibCreateEntry (
+ IN SMBIOS_STRUCTURE *SmbiosEntry,
+ IN CHAR8 **StringArray
+ );
+
+
+/**
+ Update the string associated with an existing SMBIOS record.
+
+ This function allows the update of specific SMBIOS strings. The number of valid strings for any
+ SMBIOS record is defined by how many strings were present when Add() was called.
+
+ @param[in] SmbiosHandle SMBIOS Handle of structure that will have its string updated.
+ @param[in] StringNumber The non-zero string number of the string to update.
+ @param[in] String Update the StringNumber string with String.
+
+ @retval EFI_SUCCESS SmbiosHandle had its StringNumber String updated.
+ @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. Or String is invalid.
+ @retval EFI_UNSUPPORTED String was not added because it is longer than the SMBIOS Table supports.
+ @retval EFI_NOT_FOUND The StringNumber.is not valid for this SMBIOS record.
+**/
+EFI_STATUS
+EFIAPI
+SmbiosLibUpdateString (
+ IN EFI_SMBIOS_HANDLE SmbiosHandle,
+ IN SMBIOS_TABLE_STRING StringNumber,
+ IN CHAR8 *String
+ );
+
+/**
+ Update the string associated with an existing SMBIOS record.
+
+ This function allows the update of specific SMBIOS strings. The number of valid strings for any
+ SMBIOS record is defined by how many strings were present when Add() was called.
+
+ @param[in] SmbiosHandle SMBIOS Handle of structure that will have its string updated.
+ @param[in] StringNumber The non-zero string number of the string to update.
+ @param[in] String Update the StringNumber string with String.
+
+ @retval EFI_SUCCESS SmbiosHandle had its StringNumber String updated.
+ @retval EFI_INVALID_PARAMETER SmbiosHandle does not exist. Or String is invalid.
+ @retval EFI_UNSUPPORTED String was not added because it is longer than the SMBIOS Table supports.
+ @retval EFI_NOT_FOUND The StringNumber.is not valid for this SMBIOS record.
+**/
+EFI_STATUS
+EFIAPI
+SmbiosLibUpdateUnicodeString (
+ IN EFI_SMBIOS_HANDLE SmbiosHandle,
+ IN SMBIOS_TABLE_STRING StringNumber,
+ IN CHAR16 *String
+ );
+
+/**
+ Allow caller to read a specific SMBIOS string
+
+ @param[in] Header SMBIOS record that contains the string.
+ @param[in[ StringNumber Instance of SMBIOS string 1 - N.
+
+ @retval NULL Instance of Type SMBIOS string was not found.
+ @retval Other Pointer to matching SMBIOS string.
+**/
+CHAR8 *
+EFIAPI
+SmbiosLibReadString (
+ IN SMBIOS_STRUCTURE *Header,
+ IN EFI_SMBIOS_STRING StringNumber
+ );
+
+
+/**
+ Allow the caller to discover a specific SMBIOS entry, and patch it if necissary.
+
+ @param[in] Type Type of the next SMBIOS record to return.
+ @param[in[ Instance Instance of SMBIOS record 0 - N-1.
+ @param[out] SmbiosHandle Returns SMBIOS handle for the matching record.
+
+ @retval NULL Instance of Type SMBIOS record was not found.
+ @retval Other Pointer to matching SMBIOS record.
+**/
+SMBIOS_STRUCTURE *
+EFIAPI
+SmbiosLibGetRecord (
+ IN EFI_SMBIOS_TYPE Type,
+ IN UINTN Instance,
+ OUT EFI_SMBIOS_HANDLE *SmbiosHandle
+ );
+
+/**
+ Remove an SMBIOS record.
+
+ This function removes an SMBIOS record using the handle specified by SmbiosHandle.
+
+ @param[in] SmbiosHandle The handle of the SMBIOS record to remove.
+
+ @retval EFI_SUCCESS SMBIOS record was removed.
+ @retval EFI_INVALID_PARAMETER SmbiosHandle does not specify a valid SMBIOS record.
+**/
+EFI_STATUS
+EFIAPI
+SmbiosLibRemove (
+ OUT EFI_SMBIOS_HANDLE SmbiosHandle
+ );
+
+
+
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Library/ThunkPpiList.h b/CdeEmuPkg/EmulatorPkg/Include/Library/ThunkPpiList.h
new file mode 100644
index 00000000000..dcef5be4ef2
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Library/ThunkPpiList.h
@@ -0,0 +1,27 @@
+/** @file
+ All 3rd parties to register the PPIs passed into PEI Core
+
+ Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include
+
+
+EFI_PEI_PPI_DESCRIPTOR *
+GetThunkPpiList (
+ VOID
+ );
+
+
+EFI_STATUS
+EFIAPI
+AddThunkPpi (
+ IN UINTN Flags,
+ IN EFI_GUID *Guid,
+ IN VOID *Ppi
+ );
+
+
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Library/ThunkProtocolList.h b/CdeEmuPkg/EmulatorPkg/Include/Library/ThunkProtocolList.h
new file mode 100644
index 00000000000..6bec31482b0
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Library/ThunkProtocolList.h
@@ -0,0 +1,29 @@
+/** @file
+ Emulator Thunk to abstract OS services from pure EFI code
+
+ Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include
+#include
+
+
+EFI_STATUS
+EFIAPI
+AddThunkProtocol (
+ IN EMU_IO_THUNK_PROTOCOL *ThunkIo,
+ IN CHAR16 *ConfigString,
+ IN BOOLEAN EmuBusDriver
+ );
+
+EFI_STATUS
+EFIAPI
+GetNextThunkProtocol (
+ IN BOOLEAN EmuBusDriver,
+ OUT EMU_IO_THUNK_PROTOCOL **Instance
+ );
+
+
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Ppi/EmuThunk.h b/CdeEmuPkg/EmulatorPkg/Include/Ppi/EmuThunk.h
new file mode 100644
index 00000000000..ad7e73c0ad1
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Ppi/EmuThunk.h
@@ -0,0 +1,121 @@
+/** @file
+ Emulator Thunk to abstract OS services from pure EFI code
+
+ Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EMU_THUNK_PPI_H__
+#define __EMU_THUNK_PPI_H__
+
+#define EMU_THUNK_PPI_GUID \
+ { 0xB958B78C, 0x1D3E, 0xEE40, { 0x8B, 0xF4, 0xF0, 0x63, 0x2D, 0x06, 0x39, 0x16 } }
+
+
+
+/*++
+
+Routine Description:
+ This service is called from Index == 0 until it returns EFI_UNSUPPORTED.
+ It allows discontinuous memory regions to be supported by the emulator.
+
+Arguments:
+ Index - Which memory region to use
+ MemoryBase - Return Base address of memory region
+ MemorySize - Return size in bytes of the memory region
+
+Returns:
+ EFI_SUCCESS - If memory region was mapped
+ EFI_UNSUPPORTED - If Index is not supported
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_PEI_AUTOSCAN) (
+ IN UINTN Index,
+ OUT EFI_PHYSICAL_ADDRESS *MemoryBase,
+ OUT UINT64 *MemorySize
+ );
+
+
+/*++
+
+Routine Description:
+ Return the FD Size and base address. Since the FD is loaded from a
+ file into host memory only the SEC will know it's address.
+
+Arguments:
+ Index - Which FD, starts at zero.
+ FdSize - Size of the FD in bytes
+ FdBase - Start address of the FD. Assume it points to an FV Header
+ FixUp - Difference between actual FD address and build address
+
+Returns:
+ EFI_SUCCESS - Return the Base address and size of the FV
+ EFI_UNSUPPORTED - Index does nto map to an FD in the system
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_PEI_FD_INFORMATION) (
+ IN UINTN Index,
+ IN OUT EFI_PHYSICAL_ADDRESS *FdBase,
+ IN OUT UINT64 *FdSize,
+ IN OUT EFI_PHYSICAL_ADDRESS *FixUp
+ );
+
+
+/*++
+
+Routine Description:
+ Export of EMU_THUNK_PROTOCOL from the SEC.
+
+Returns:
+ EFI_SUCCESS - Data returned
+
+**/
+typedef
+VOID *
+(EFIAPI *EMU_PEI_THUNK_INTERFACE) (
+ VOID
+ );
+
+
+
+/*++
+
+Routine Description:
+ Loads and relocates a PE/COFF image into memory.
+
+Arguments:
+ Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated
+ ImageAddress - The base address of the relocated PE/COFF image
+ ImageSize - The size of the relocated PE/COFF image
+ EntryPoint - The entry point of the relocated PE/COFF image
+
+Returns:
+ EFI_SUCCESS - The file was loaded and relocated
+ EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_PEI_LOAD_FILE) (
+ VOID *Pe32Data,
+ EFI_PHYSICAL_ADDRESS *ImageAddress,
+ UINT64 *ImageSize,
+ EFI_PHYSICAL_ADDRESS *EntryPoint
+ );
+
+
+typedef struct {
+ EMU_PEI_AUTOSCAN MemoryAutoScan;
+ EMU_PEI_FD_INFORMATION FirmwareDevices;
+ EMU_PEI_THUNK_INTERFACE Thunk;
+} EMU_THUNK_PPI;
+
+extern EFI_GUID gEmuThunkPpiGuid;
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuBlockIo.h b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuBlockIo.h
new file mode 100644
index 00000000000..83cc93fdc3b
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuBlockIo.h
@@ -0,0 +1,186 @@
+/** @file
+ Emu Block IO2 protocol as defined in the UEFI 2.3.1 specification.
+
+ The Block IO2 protocol defines an extension to the Block IO protocol which
+ enables the ability to read and write data at a block level in a non-blocking
+ manner.
+
+ Copyright (c) 2011, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EMU_BLOCK_IO_H__
+#define __EMU_BLOCK_IO_H__
+
+#include
+#include
+
+#define EMU_BLOCK_IO_PROTOCOL_GUID \
+{ 0x6888A4AE, 0xAFCE, 0xE84B, { 0x91, 0x02, 0xF7, 0xB9, 0xDA, 0xE6, 0xA0, 0x30 } }
+
+typedef struct _EMU_BLOCK_IO_PROTOCOL EMU_BLOCK_IO_PROTOCOL;
+
+
+
+/**
+ Reset the block device hardware.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] ExtendedVerification Indicates that the driver may perform a more
+ exhausive verfication operation of the device
+ during reset.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could
+ not be reset.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_BLOCK_RESET) (
+ IN EMU_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+/**
+ Read BufferSize bytes from Lba into Buffer.
+
+ This function reads the requested number of blocks from the device. All the
+ blocks are read, or an error is returned.
+ If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_or EFI_MEDIA_CHANGED is returned and
+ non-blocking I/O is being used, the Event associated with this request will
+ not be signaled.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] MediaId Id of the media, changes every time the media is
+ replaced.
+ @param[in] Lba The starting Logical Block Address to read from.
+ @param[in, out] Token A pointer to the token associated with the transaction.
+ @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
+ @param[out] Buffer A pointer to the destination buffer for the data. The
+ caller is responsible for either having implicit or
+ explicit ownership of the buffer.
+
+ @retval EFI_SUCCESS The read request was queued if Token->Event is
+ not NULL.The data was read correctly from the
+ device if the Token->Event is NULL.
+ @retval EFI_DEVICE_ERROR The device reported an error while performing
+ the read.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
+ @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the
+ intrinsic block size of the device.
+ @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
+ or the buffer is not on proper alignment.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
+ of resources.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_BLOCK_READ) (
+ IN EMU_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN OUT EFI_BLOCK_IO2_TOKEN *Token,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+/**
+ Write BufferSize bytes from Lba into Buffer.
+
+ This function writes the requested number of blocks to the device. All blocks
+ are written, or an error is returned.If EFI_DEVICE_ERROR, EFI_NO_MEDIA,
+ EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED is returned and non-blocking I/O is
+ being used, the Event associated with this request will not be signaled.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in] MediaId The media ID that the write request is for.
+ @param[in] Lba The starting logical block address to be written. The
+ caller is responsible for writing to only legitimate
+ locations.
+ @param[in, out] Token A pointer to the token associated with the transaction.
+ @param[in] BufferSize Size of Buffer, must be a multiple of device block size.
+ @param[in] Buffer A pointer to the source buffer for the data.
+
+ @retval EFI_SUCCESS The write request was queued if Event is not NULL.
+ The data was written correctly to the device if
+ the Event is NULL.
+ @retval EFI_WRITE_PROTECTED The device can not be written to.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
+ @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
+ or the buffer is not on proper alignment.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
+ of resources.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_BLOCK_WRITE) (
+ IN EMU_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN OUT EFI_BLOCK_IO2_TOKEN *Token,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ );
+
+/**
+ Flush the Block Device.
+
+ If EFI_DEVICE_ERROR, EFI_NO_MEDIA,_EFI_WRITE_PROTECTED or EFI_MEDIA_CHANGED
+ is returned and non-blocking I/O is being used, the Event associated with
+ this request will not be signaled.
+
+ @param[in] This Indicates a pointer to the calling context.
+ @param[in,out] Token A pointer to the token associated with the transaction
+
+ @retval EFI_SUCCESS The flush request was queued if Event is not NULL.
+ All outstanding data was written correctly to the
+ device if the Event is NULL.
+ @retval EFI_DEVICE_ERROR The device reported an error while writting back
+ the data.
+ @retval EFI_WRITE_PROTECTED The device cannot be written to.
+ @retval EFI_NO_MEDIA There is no media in the device.
+ @retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack
+ of resources.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_BLOCK_FLUSH) (
+ IN EMU_BLOCK_IO_PROTOCOL *This,
+ IN OUT EFI_BLOCK_IO2_TOKEN *Token
+ );
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_BLOCK_CREATE_MAPPING) (
+ IN EMU_BLOCK_IO_PROTOCOL *This,
+ IN EFI_BLOCK_IO_MEDIA *Media
+ );
+
+
+///
+/// The Block I/O2 protocol defines an extension to the Block I/O protocol which
+/// enables the ability to read and write data at a block level in a non-blocking
+// manner.
+///
+struct _EMU_BLOCK_IO_PROTOCOL {
+ EMU_BLOCK_RESET Reset;
+ EMU_BLOCK_READ ReadBlocks;
+ EMU_BLOCK_WRITE WriteBlocks;
+ EMU_BLOCK_FLUSH FlushBlocks;
+ EMU_BLOCK_CREATE_MAPPING CreateMapping;
+};
+
+extern EFI_GUID gEmuBlockIoProtocolGuid;
+
+#endif
+
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuFileSystem.h b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuFileSystem.h
new file mode 100644
index 00000000000..a247eb85bc1
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuFileSystem.h
@@ -0,0 +1,134 @@
+/** @file
+ SimpleFileSystem protocol as defined in the UEFI 2.0 specification.
+
+ The SimpleFileSystem protocol is the programmatic access to the FAT (12,16,32)
+ file system specified in UEFI 2.0. It can also be used to abstract a file
+ system other than FAT.
+
+ UEFI 2.0 can boot from any valid EFI image contained in a SimpleFileSystem.
+
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EMU_UGA_IO_H_
+#define _EMU_UGA_IO_H_
+
+#include
+#include
+#include
+#include
+
+#define EMU_GRAPHICS_WINDOW_PROTOCOL_GUID \
+ { 0x30FD316A, 0x6728, 0x2E41, { 0xA6, 0x90, 0x0D, 0x13, 0x33, 0xD8, 0xCA, 0xC1 } }
+
+typedef struct _EMU_GRAPHICS_WINDOW_PROTOCOL EMU_GRAPHICS_WINDOW_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_CLOSE)(
+ EMU_GRAPHICS_WINDOW_PROTOCOL *Uga
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_SIZE)(
+ EMU_GRAPHICS_WINDOW_PROTOCOL *Uga,
+ UINT32 Width,
+ UINT32 Height
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_CHECK_KEY)(
+ EMU_GRAPHICS_WINDOW_PROTOCOL *Uga
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_GET_KEY)(
+ EMU_GRAPHICS_WINDOW_PROTOCOL *Uga,
+ EFI_KEY_DATA *key
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_KEY_SET_STATE) (
+ IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+ );
+
+
+typedef
+VOID
+(EFIAPI *EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK) (
+ IN VOID *Context,
+ IN EFI_KEY_DATA *KeyData
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_REGISTER_KEY_NOTIFY) (
+ IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows,
+ IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK CallBack,
+ IN VOID *Context
+ );
+
+
+typedef struct {
+ UINTN SourceX;
+ UINTN SourceY;
+ UINTN DestinationX;
+ UINTN DestinationY;
+ UINTN Width;
+ UINTN Height;
+ UINTN Delta;
+} EMU_GRAPHICS_WINDOWS__BLT_ARGS;
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_BLT)(
+ IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows,
+ IN EFI_UGA_PIXEL *BltBuffer OPTIONAL,
+ IN EFI_UGA_BLT_OPERATION BltOperation,
+ IN EMU_GRAPHICS_WINDOWS__BLT_ARGS *Args
+ );
+
+typedef
+BOOLEAN
+(EFIAPI *EMU_GRAPHICS_WINDOWS_IS_KEY_PRESSED) (
+ IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows,
+ IN EFI_KEY_DATA *KeyData
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_CHECK_POINTER)(
+ EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_GET_POINTER_STATE)(
+ EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows,
+ EFI_SIMPLE_POINTER_STATE *state
+ );
+
+struct _EMU_GRAPHICS_WINDOW_PROTOCOL {
+ EMU_GRAPHICS_WINDOWS_SIZE Size;
+ EMU_GRAPHICS_WINDOWS_CHECK_KEY CheckKey;
+ EMU_GRAPHICS_WINDOWS_KEY_SET_STATE KeySetState;
+ EMU_GRAPHICS_WINDOWS_GET_KEY GetKey;
+ EMU_GRAPHICS_WINDOWS_REGISTER_KEY_NOTIFY RegisterKeyNotify;
+ EMU_GRAPHICS_WINDOWS_BLT Blt;
+ EMU_GRAPHICS_WINDOWS_IS_KEY_PRESSED IsKeyPressed;
+ EMU_GRAPHICS_WINDOWS_CHECK_POINTER CheckPointer;
+ EMU_GRAPHICS_WINDOWS_GET_POINTER_STATE GetPointerState;
+};
+
+
+extern EFI_GUID gEmuGraphicsWindowProtocolGuid;
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuGraphicsWindow.h b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuGraphicsWindow.h
new file mode 100644
index 00000000000..3d3eb3126bf
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuGraphicsWindow.h
@@ -0,0 +1,128 @@
+/*++ @file
+
+Copyright (c) 2006, Tristan Gingold. All rights reserved.
+Portitions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EMU_UGA_IO_H_
+#define _EMU_UGA_IO_H_
+
+#include
+#include
+#include
+#include
+
+#define EMU_GRAPHICS_WINDOW_PROTOCOL_GUID \
+ { 0x30FD316A, 0x6728, 0x2E41, { 0xA6, 0x90, 0x0D, 0x13, 0x33, 0xD8, 0xCA, 0xC1 } }
+
+typedef struct _EMU_GRAPHICS_WINDOW_PROTOCOL EMU_GRAPHICS_WINDOW_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_CLOSE)(
+ EMU_GRAPHICS_WINDOW_PROTOCOL *Uga
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_SIZE)(
+ EMU_GRAPHICS_WINDOW_PROTOCOL *Uga,
+ UINT32 Width,
+ UINT32 Height
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_CHECK_KEY)(
+ EMU_GRAPHICS_WINDOW_PROTOCOL *Uga
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_GET_KEY)(
+ EMU_GRAPHICS_WINDOW_PROTOCOL *Uga,
+ EFI_KEY_DATA *key
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_KEY_SET_STATE) (
+ IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+ );
+
+
+typedef
+VOID
+(EFIAPI *EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK) (
+ IN VOID *Context,
+ IN EFI_KEY_DATA *KeyData
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_REGISTER_KEY_NOTIFY) (
+ IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows,
+ IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeCallBack,
+ IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakCallBack,
+ IN VOID *Context
+ );
+
+
+typedef struct {
+ UINTN SourceX;
+ UINTN SourceY;
+ UINTN DestinationX;
+ UINTN DestinationY;
+ UINTN Width;
+ UINTN Height;
+ UINTN Delta;
+} EMU_GRAPHICS_WINDOWS__BLT_ARGS;
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_BLT)(
+ IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows,
+ IN EFI_UGA_PIXEL *BltBuffer OPTIONAL,
+ IN EFI_UGA_BLT_OPERATION BltOperation,
+ IN EMU_GRAPHICS_WINDOWS__BLT_ARGS *Args
+ );
+
+typedef
+BOOLEAN
+(EFIAPI *EMU_GRAPHICS_WINDOWS_IS_KEY_PRESSED) (
+ IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows,
+ IN EFI_KEY_DATA *KeyData
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_CHECK_POINTER)(
+ EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GRAPHICS_WINDOWS_GET_POINTER_STATE)(
+ EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindows,
+ EFI_SIMPLE_POINTER_STATE *state
+ );
+
+struct _EMU_GRAPHICS_WINDOW_PROTOCOL {
+ EMU_GRAPHICS_WINDOWS_SIZE Size;
+ EMU_GRAPHICS_WINDOWS_CHECK_KEY CheckKey;
+ EMU_GRAPHICS_WINDOWS_KEY_SET_STATE KeySetState;
+ EMU_GRAPHICS_WINDOWS_GET_KEY GetKey;
+ EMU_GRAPHICS_WINDOWS_REGISTER_KEY_NOTIFY RegisterKeyNotify;
+ EMU_GRAPHICS_WINDOWS_BLT Blt;
+ EMU_GRAPHICS_WINDOWS_IS_KEY_PRESSED IsKeyPressed;
+ EMU_GRAPHICS_WINDOWS_CHECK_POINTER CheckPointer;
+ EMU_GRAPHICS_WINDOWS_GET_POINTER_STATE GetPointerState;
+};
+
+
+extern EFI_GUID gEmuGraphicsWindowProtocolGuid;
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuIoThunk.h b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuIoThunk.h
new file mode 100644
index 00000000000..9e27e7cd16d
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuIoThunk.h
@@ -0,0 +1,45 @@
+/** @file
+ Emulator Thunk to abstract OS services from pure EFI code
+
+ Copyright (c) 2010 - 2011, Apple Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EMU_IO_THUNK__
+#define __EMU_IO_THUNK__
+
+
+#define EMU_IO_THUNK_PROTOCO_GUID \
+ { 0x453368F6, 0x7C85, 0x434A, { 0xA9, 0x8A, 0x72, 0xD1, 0xB7, 0xFF, 0xA9, 0x26 } }
+
+
+typedef struct _EMU_IO_THUNK_PROTOCOL EMU_IO_THUNK_PROTOCOL;
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_IO_THUNK_PROTOCOL_CLOSE_OPEN) (
+ IN EMU_IO_THUNK_PROTOCOL *This
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_IO_THUNK_PROTOCOL_CLOSE_CLOSE) (
+ IN EMU_IO_THUNK_PROTOCOL *This
+ );
+
+struct _EMU_IO_THUNK_PROTOCOL {
+ EFI_GUID *Protocol;
+ VOID *Interface; /// Only be valid after Open() is called
+ CHAR16 *ConfigString;
+ UINT16 Instance;
+ EMU_IO_THUNK_PROTOCOL_CLOSE_OPEN Open;
+ EMU_IO_THUNK_PROTOCOL_CLOSE_CLOSE Close;
+ VOID *Private; /// Used by implementation
+};
+
+extern EFI_GUID gEmuIoThunkProtocolGuid;
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuSnp.h b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuSnp.h
new file mode 100644
index 00000000000..a422a3ea339
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuSnp.h
@@ -0,0 +1,453 @@
+/** @file
+ The EMU_SNP_PROTOCOL provides services to initialize a network interface,
+ transmit packets, receive packets, and close a network interface.
+
+
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Portitions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EMU_SNP_H__
+#define __EMU_SNP_H__
+
+#include
+
+#define EMU_SNP_PROTOCOL_GUID \
+ { 0xFD5FBE54, 0x8C35, 0xB345, { 0x8A, 0x0F, 0x7A, 0xC8, 0xA5, 0xFD, 0x05, 0x21 } }
+
+typedef struct _EMU_SNP_PROTOCOL EMU_SNP_PROTOCOL;
+
+
+/**
+ Register storage for SNP Mode.
+
+ @param This Protocol instance pointer.
+ @param Mode SimpleNetworkProtocol Mode structure passed into driver.
+
+ @retval EFI_SUCCESS The network interface was started.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_CREATE_MAPPING)(
+ IN EMU_SNP_PROTOCOL *This,
+ IN EFI_SIMPLE_NETWORK_MODE *Mode
+ );
+
+
+/**
+ Changes the state of a network interface from "stopped" to "started".
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS The network interface was started.
+ @retval EFI_ALREADY_STARTED The network interface is already in the started state.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_START)(
+ IN EMU_SNP_PROTOCOL *This
+ );
+
+/**
+ Changes the state of a network interface from "started" to "stopped".
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS The network interface was stopped.
+ @retval EFI_ALREADY_STARTED The network interface is already in the stopped state.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_STOP)(
+ IN EMU_SNP_PROTOCOL *This
+ );
+
+/**
+ Resets a network adapter and allocates the transmit and receive buffers
+ required by the network interface; optionally, also requests allocation
+ of additional transmit and receive buffers.
+
+ @param This The protocol instance pointer.
+ @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space
+ that the driver should allocate for the network interface.
+ Some network interfaces will not be able to use the extra
+ buffer, and the caller will not know if it is actually
+ being used.
+ @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space
+ that the driver should allocate for the network interface.
+ Some network interfaces will not be able to use the extra
+ buffer, and the caller will not know if it is actually
+ being used.
+
+ @retval EFI_SUCCESS The network interface was initialized.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and
+ receive buffers.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_INITIALIZE)(
+ IN EMU_SNP_PROTOCOL *This,
+ IN UINTN ExtraRxBufferSize OPTIONAL,
+ IN UINTN ExtraTxBufferSize OPTIONAL
+ );
+
+/**
+ Resets a network adapter and re-initializes it with the parameters that were
+ provided in the previous call to Initialize().
+
+ @param This The protocol instance pointer.
+ @param ExtendedVerification Indicates that the driver may perform a more
+ exhaustive verification operation of the device
+ during reset.
+
+ @retval EFI_SUCCESS The network interface was reset.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_RESET)(
+ IN EMU_SNP_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+/**
+ Resets a network adapter and leaves it in a state that is safe for
+ another driver to initialize.
+
+ @param This Protocol instance pointer.
+
+ @retval EFI_SUCCESS The network interface was shutdown.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_SHUTDOWN)(
+ IN EMU_SNP_PROTOCOL *This
+ );
+
+/**
+ Manages the multicast receive filters of a network interface.
+
+ @param This The protocol instance pointer.
+ @param Enable A bit mask of receive filters to enable on the network interface.
+ @param Disable A bit mask of receive filters to disable on the network interface.
+ @param ResetMCastFilter Set to TRUE to reset the contents of the multicast receive
+ filters on the network interface to their default values.
+ @param McastFilterCnt Number of multicast HW MAC addresses in the new
+ MCastFilter list. This value must be less than or equal to
+ the MCastFilterCnt field of EMU_SNP_MODE. This
+ field is optional if ResetMCastFilter is TRUE.
+ @param MCastFilter A pointer to a list of new multicast receive filter HW MAC
+ addresses. This list will replace any existing multicast
+ HW MAC address list. This field is optional if
+ ResetMCastFilter is TRUE.
+
+ @retval EFI_SUCCESS The multicast receive filter list was updated.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_RECEIVE_FILTERS)(
+ IN EMU_SNP_PROTOCOL *This,
+ IN UINT32 Enable,
+ IN UINT32 Disable,
+ IN BOOLEAN ResetMCastFilter,
+ IN UINTN MCastFilterCnt OPTIONAL,
+ IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL
+ );
+
+/**
+ Modifies or resets the current station address, if supported.
+
+ @param This The protocol instance pointer.
+ @param Reset Flag used to reset the station address to the network interfaces
+ permanent address.
+ @param New The new station address to be used for the network interface.
+
+ @retval EFI_SUCCESS The network interfaces station address was updated.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_STATION_ADDRESS)(
+ IN EMU_SNP_PROTOCOL *This,
+ IN BOOLEAN Reset,
+ IN EFI_MAC_ADDRESS *New OPTIONAL
+ );
+
+/**
+ Resets or collects the statistics on a network interface.
+
+ @param This Protocol instance pointer.
+ @param Reset Set to TRUE to reset the statistics for the network interface.
+ @param StatisticsSize On input the size, in bytes, of StatisticsTable. On
+ output the size, in bytes, of the resulting table of
+ statistics.
+ @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
+ contains the statistics.
+
+ @retval EFI_SUCCESS The statistics were collected from the network interface.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer
+ size needed to hold the statistics is returned in
+ StatisticsSize.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_STATISTICS)(
+ IN EMU_SNP_PROTOCOL *This,
+ IN BOOLEAN Reset,
+ IN OUT UINTN *StatisticsSize OPTIONAL,
+ OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL
+ );
+
+/**
+ Converts a multicast IP address to a multicast HW MAC address.
+
+ @param This The protocol instance pointer.
+ @param IPv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set
+ to FALSE if the multicast IP address is IPv4 [RFC 791].
+ @param IP The multicast IP address that is to be converted to a multicast
+ HW MAC address.
+ @param MAC The multicast HW MAC address that is to be generated from IP.
+
+ @retval EFI_SUCCESS The multicast IP address was mapped to the multicast
+ HW MAC address.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer
+ size needed to hold the statistics is returned in
+ StatisticsSize.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_MCAST_IP_TO_MAC)(
+ IN EMU_SNP_PROTOCOL *This,
+ IN BOOLEAN IPv6,
+ IN EFI_IP_ADDRESS *IP,
+ OUT EFI_MAC_ADDRESS *MAC
+ );
+
+/**
+ Performs read and write operations on the NVRAM device attached to a
+ network interface.
+
+ @param This The protocol instance pointer.
+ @param ReadWrite TRUE for read operations, FALSE for write operations.
+ @param Offset Byte offset in the NVRAM device at which to start the read or
+ write operation. This must be a multiple of NvRamAccessSize and
+ less than NvRamSize.
+ @param BufferSize The number of bytes to read or write from the NVRAM device.
+ This must also be a multiple of NvramAccessSize.
+ @param Buffer A pointer to the data buffer.
+
+ @retval EFI_SUCCESS The NVRAM access was performed.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_NVDATA)(
+ IN EMU_SNP_PROTOCOL *This,
+ IN BOOLEAN ReadWrite,
+ IN UINTN Offset,
+ IN UINTN BufferSize,
+ IN OUT VOID *Buffer
+ );
+
+/**
+ Reads the current interrupt status and recycled transmit buffer status from
+ a network interface.
+
+ @param This The protocol instance pointer.
+ @param InterruptStatus A pointer to the bit mask of the currently active interrupts
+ If this is NULL, the interrupt status will not be read from
+ the device. If this is not NULL, the interrupt status will
+ be read from the device. When the interrupt status is read,
+ it will also be cleared. Clearing the transmit interrupt
+ does not empty the recycled transmit buffer array.
+ @param TxBuf Recycled transmit buffer address. The network interface will
+ not transmit if its internal recycled transmit buffer array
+ is full. Reading the transmit buffer does not clear the
+ transmit interrupt. If this is NULL, then the transmit buffer
+ status will not be read. If there are no transmit buffers to
+ recycle and TxBuf is not NULL, * TxBuf will be set to NULL.
+
+ @retval EFI_SUCCESS The status of the network interface was retrieved.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_GET_STATUS)(
+ IN EMU_SNP_PROTOCOL *This,
+ OUT UINT32 *InterruptStatus OPTIONAL,
+ OUT VOID **TxBuf OPTIONAL
+ );
+
+/**
+ Places a packet in the transmit queue of a network interface.
+
+ @param This The protocol instance pointer.
+ @param HeaderSize The size, in bytes, of the media header to be filled in by
+ the Transmit() function. If HeaderSize is non-zero, then it
+ must be equal to This->Mode->MediaHeaderSize and the DestAddr
+ and Protocol parameters must not be NULL.
+ @param BufferSize The size, in bytes, of the entire packet (media header and
+ data) to be transmitted through the network interface.
+ @param Buffer A pointer to the packet (media header followed by data) to be
+ transmitted. This parameter cannot be NULL. If HeaderSize is zero,
+ then the media header in Buffer must already be filled in by the
+ caller. If HeaderSize is non-zero, then the media header will be
+ filled in by the Transmit() function.
+ @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter
+ is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then
+ This->Mode->CurrentAddress is used for the source HW MAC address.
+ @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this
+ parameter is ignored.
+ @param Protocol The type of header to build. If HeaderSize is zero, then this
+ parameter is ignored. See RFC 1700, section "Ether Types", for
+ examples.
+
+ @retval EFI_SUCCESS The packet was placed on the transmit queue.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_TRANSMIT)(
+ IN EMU_SNP_PROTOCOL *This,
+ IN UINTN HeaderSize,
+ IN UINTN BufferSize,
+ IN VOID *Buffer,
+ IN EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
+ IN EFI_MAC_ADDRESS *DestAddr OPTIONAL,
+ IN UINT16 *Protocol OPTIONAL
+ );
+
+/**
+ Receives a packet from a network interface.
+
+ @param This The protocol instance pointer.
+ @param HeaderSize The size, in bytes, of the media header received on the network
+ interface. If this parameter is NULL, then the media header size
+ will not be returned.
+ @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in
+ bytes, of the packet that was received on the network interface.
+ @param Buffer A pointer to the data buffer to receive both the media header and
+ the data.
+ @param SrcAddr The source HW MAC address. If this parameter is NULL, the
+ HW MAC source address will not be extracted from the media
+ header.
+ @param DestAddr The destination HW MAC address. If this parameter is NULL,
+ the HW MAC destination address will not be extracted from the
+ media header.
+ @param Protocol The media header type. If this parameter is NULL, then the
+ protocol will not be extracted from the media header. See
+ RFC 1700 section "Ether Types" for examples.
+
+ @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has
+ been updated to the number of bytes received.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_NOT_READY The network interface is too busy to accept this transmit
+ request.
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_SNP_RECEIVE)(
+ IN EMU_SNP_PROTOCOL *This,
+ OUT UINTN *HeaderSize OPTIONAL,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer,
+ OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
+ OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL,
+ OUT UINT16 *Protocol OPTIONAL
+ );
+
+#define EMU_SNP_PROTOCOL_REVISION 0x00010000
+
+//
+// Revision defined in EFI1.1
+//
+#define EMU_SNP_INTERFACE_REVISION EMU_SNP_PROTOCOL_REVISION
+
+///
+/// The EMU_SNP_PROTOCOL protocol abstracts OS network sercices
+/// from the EFI driver that produces EFI Simple Network Protocol.
+///
+struct _EMU_SNP_PROTOCOL {
+ EMU_SNP_CREATE_MAPPING CreateMapping;
+ EMU_SNP_START Start;
+ EMU_SNP_STOP Stop;
+ EMU_SNP_INITIALIZE Initialize;
+ EMU_SNP_RESET Reset;
+ EMU_SNP_SHUTDOWN Shutdown;
+ EMU_SNP_RECEIVE_FILTERS ReceiveFilters;
+ EMU_SNP_STATION_ADDRESS StationAddress;
+ EMU_SNP_STATISTICS Statistics;
+ EMU_SNP_MCAST_IP_TO_MAC MCastIpToMac;
+ EMU_SNP_NVDATA NvData;
+ EMU_SNP_GET_STATUS GetStatus;
+ EMU_SNP_TRANSMIT Transmit;
+ EMU_SNP_RECEIVE Receive;
+};
+
+extern EFI_GUID gEmuSnpProtocolGuid;
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuThread.h b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuThread.h
new file mode 100644
index 00000000000..14a6df57b83
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuThread.h
@@ -0,0 +1,97 @@
+/** @file
+ Emulator Thunk to abstract OS services from pure EFI code
+
+ Copyright (c) 2010 - 2011, Apple Inc. All rights reserved.
+ Copyright (c) 2011, Intel Corporation. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EMU_THREAD_THUNK__
+#define __EMU_THREAD_THUNK__
+
+
+typedef struct _EMU_THREAD_THUNK_PROTOCOL EMU_THREAD_THUNK_PROTOCOL;
+
+
+typedef
+UINTN
+(EFIAPI *THREAD_THUNK_MUTEX_LOCK) (
+ IN VOID *Mutex
+ );
+
+
+typedef
+UINTN
+(EFIAPI *THREAD_THUNK_MUTEX_UNLOCK) (
+ IN VOID *Mutex
+ );
+
+
+typedef
+UINTN
+(EFIAPI *THREAD_THUNK_MUTEX_TRY_LOCK) (
+ IN VOID *Mutex
+ );
+
+
+typedef
+VOID *
+(EFIAPI *THREAD_THUNK_MUTEX_INIT) (
+ IN VOID
+ );
+
+
+typedef
+UINTN
+(EFIAPI *THREAD_THUNK_MUTEX_DISTROY) (
+ IN VOID *Mutex
+ );
+
+
+
+typedef
+VOID *
+(EFIAPI *THREAD_THUNK_THREAD_ENTRY) (
+ IN VOID *Context
+ );
+
+typedef
+UINTN
+(EFIAPI *THREAD_THUNK_CREATE_THREAD) (
+ IN VOID *Thread,
+ IN VOID *Attribute,
+ IN THREAD_THUNK_THREAD_ENTRY Start,
+ IN VOID *Context
+ );
+
+typedef
+VOID
+(EFIAPI *THREAD_THUNK_EXIT_THREAD) (
+ IN VOID *ValuePtr
+ );
+
+
+typedef
+UINTN
+(EFIAPI *THREAD_THUNK_SELF) (
+ VOID
+ );
+
+
+struct _EMU_THREAD_THUNK_PROTOCOL {
+ THREAD_THUNK_MUTEX_LOCK MutexLock;
+ THREAD_THUNK_MUTEX_UNLOCK MutexUnlock;
+ THREAD_THUNK_MUTEX_TRY_LOCK MutexTryLock;
+ THREAD_THUNK_MUTEX_INIT MutexInit;
+ THREAD_THUNK_MUTEX_DISTROY MutexDistroy;
+ THREAD_THUNK_CREATE_THREAD CreateThread;
+ THREAD_THUNK_EXIT_THREAD ExitThread;
+ THREAD_THUNK_SELF Self;
+};
+
+extern EFI_GUID gEmuThreadThunkProtocolGuid;
+
+#endif
+
diff --git a/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuThunk.h b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuThunk.h
new file mode 100644
index 00000000000..ffda2d6d0d5
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Include/Protocol/EmuThunk.h
@@ -0,0 +1,258 @@
+/** @file
+ Emulator Thunk to abstract OS services from pure EFI code
+
+ Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EMU_THUNK_PROTOCOL_H__
+#define __EMU_THUNK_PROTOCOL_H__
+
+#define EMU_THUNK_PROTOCOL_GUID \
+ { 0x5CF32E0B, 0x8EDF, 0x2E44, { 0x9C, 0xDA, 0x93, 0x20, 0x5E, 0x99, 0xEC, 0x1C } }
+
+// neded for things like EFI_TIME_CAPABILITIES
+#include
+
+#include
+
+#include
+#include
+
+
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ UINT32 Instance;
+} EMU_VENDOR_DEVICE_PATH_NODE;
+
+typedef struct {
+ EMU_VENDOR_DEVICE_PATH_NODE Vendor;
+ EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EMU_THUNK_DEVICE_PATH;
+
+
+
+typedef struct _EMU_THUNK_PROTOCOL EMU_THUNK_PROTOCOL;
+
+
+
+typedef
+UINTN
+(EFIAPI *EMU_WRITE_STD_ERROR) (
+ IN UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_CONFIG_STD_IN) (
+ VOID
+ );
+
+typedef
+UINTN
+(EFIAPI *EMU_WRITE_STD_OUT) (
+ IN UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+ );
+
+typedef
+UINTN
+(EFIAPI *EMU_READ_STD_IN) (
+ OUT UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+ );
+
+typedef
+BOOLEAN
+(EFIAPI *EMU_POLL_STD_IN) (
+ VOID
+ );
+
+
+typedef
+VOID *
+(EFIAPI *EMU_OS_MALLOC) (
+ IN UINTN Size
+ );
+
+typedef
+VOID *
+(EFIAPI *EMU_OS_VMALLOC) (
+ IN UINTN Size
+ );
+
+typedef
+BOOLEAN
+(EFIAPI *EMU_OS_FREE) (
+ IN VOID *Ptr
+ );
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EMU_PE_COFF_GET_ENTRY_POINT) (
+ IN VOID *Pe32Data,
+ IN OUT VOID **EntryPoint
+ );
+
+typedef
+VOID
+(EFIAPI *EMU_PE_COFF_RELOCATE_EXTRA_ACTION) (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ );
+
+typedef
+VOID
+(EFIAPI *EMU_PE_COFF_UNLOAD_EXTRA_ACTION) (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ );
+
+typedef
+VOID
+(EFIAPI *EMU_ENABLE_INERRUPTS) (
+ VOID
+ );
+
+typedef
+VOID
+(EFIAPI *EMU_DISABLE_INERRUPTS) (
+ VOID
+ );
+
+typedef
+UINT64
+(EFIAPI *EMU_QUERY_PERFORMANCE_FREQENCY) (
+ VOID
+ );
+
+typedef
+UINT64
+(EFIAPI *EMU_QUERY_PERFORMANCE_COUNTER) (
+ VOID
+ );
+
+typedef
+VOID
+(EFIAPI *EMU_SLEEP) (
+ IN UINT64 Milliseconds
+ );
+
+typedef
+VOID
+(EFIAPI *EMU_CPU_SLEEP) (
+ VOID
+ );
+
+typedef
+VOID
+(EFIAPI *EMU_EXIT) (
+ IN UINTN Status
+ );
+
+typedef
+VOID
+(EFIAPI *EMU_GET_TIME) (
+ OUT EFI_TIME *Time,
+ OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL
+ );
+
+typedef
+VOID
+(EFIAPI *EMU_SET_TIME) (
+ IN EFI_TIME *Time
+ );
+
+
+typedef
+VOID
+(EFIAPI EMU_SET_TIMER_CALLBACK) (
+ IN UINT64 DeltaMs
+ );
+
+typedef
+VOID
+(EFIAPI *EMU_SET_TIMER) (
+ IN UINT64 PeriodMs,
+ IN EMU_SET_TIMER_CALLBACK CallBack
+ );
+
+
+
+/**
+ Enumerates the current set of protocol instances that abstract OS services from EFI.
+
+ A given protocol can have multiple instances. Usually a protocol is configured via a
+ single PCD string. The data associated for each instance is seperated via a ! in the string.
+ EMU_IO_THUNK_PROTOCOL_CLOSE.ConfigString will contain the information in the PCD string up to the next !.
+ Thus each instance has a unique ConfigString.
+
+ @param EmuBusDriver TRUE means only return protocol instances that need to be produced
+ by the EmuBusDriver. FALSE means return all possible protocols
+ @param Instance On input the protocol to search for, or NULL to start a search
+ of all the supported protocol instances.
+ @param NextProtocol On output it represents the next value to be passed into Protocol.
+ @param Interface A pointer to the EMU_IO_THUNK_PROTOCOL_CLOSE interface.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND The next protocol instance was not found.
+ @retval EFI_INVALID_PARAMETER Instance is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EMU_GET_NEXT_PROTOCOL) (
+ IN BOOLEAN EmuBusDriver,
+ OUT EMU_IO_THUNK_PROTOCOL **Instance OPTIONAL
+ );
+
+
+struct _EMU_THUNK_PROTOCOL {
+ // Used for early debug printing
+ EMU_WRITE_STD_ERROR WriteStdErr;
+ EMU_CONFIG_STD_IN ConfigStdIn;
+ EMU_WRITE_STD_OUT WriteStdOut;
+ EMU_READ_STD_IN ReadStdIn;
+ EMU_POLL_STD_IN PollStdIn;
+
+ //
+ // Map OS malloc/free so we can use OS based guard malloc
+ //
+ EMU_OS_MALLOC Malloc;
+ EMU_OS_VMALLOC Valloc;
+ EMU_OS_FREE Free;
+
+
+ ///
+ /// PE/COFF loader hooks to get symbols loaded
+ ///
+ EMU_PE_COFF_GET_ENTRY_POINT PeCoffGetEntryPoint;
+ EMU_PE_COFF_RELOCATE_EXTRA_ACTION PeCoffRelocateImageExtraAction;
+ EMU_PE_COFF_UNLOAD_EXTRA_ACTION PeCoffUnloadImageExtraAction;
+
+ ///
+ /// DXE Architecture Protocol Services
+ ///
+ EMU_ENABLE_INERRUPTS EnableInterrupt;
+ EMU_DISABLE_INERRUPTS DisableInterrupt;
+ EMU_QUERY_PERFORMANCE_FREQENCY QueryPerformanceFrequency;
+ EMU_QUERY_PERFORMANCE_COUNTER QueryPerformanceCounter;
+
+ EMU_SLEEP Sleep;
+ EMU_CPU_SLEEP CpuSleep;
+ EMU_EXIT Exit;
+ EMU_GET_TIME GetTime;
+ EMU_SET_TIME SetTime;
+ EMU_SET_TIMER SetTimer;
+
+ ///
+ /// Generic System Services
+ ///
+ EMU_GET_NEXT_PROTOCOL GetNextProtocol;
+};
+
+extern EFI_GUID gEmuThunkProtocolGuid;
+
+#endif
diff --git a/CdeEmuPkg/EmulatorPkg/Library/DevicePathTextLib/DevicePathTextLib.c b/CdeEmuPkg/EmulatorPkg/Library/DevicePathTextLib/DevicePathTextLib.c
new file mode 100644
index 00000000000..f76c21cd331
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Library/DevicePathTextLib/DevicePathTextLib.c
@@ -0,0 +1,177 @@
+/** @file
+ Null Platform Hook Library instance.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+
+/**
+ Converts a Vendor device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ @return EFI_NOT_FOUND if no string representation exists.
+ @return EFI_SUCCESS a string representation was created.
+**/
+EFI_STATUS
+EFIAPI
+DevPathToTextVendorLib (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ EMU_VENDOR_DEVICE_PATH_NODE *Vendor;
+ CHAR16 *Type;
+
+ Vendor = (EMU_VENDOR_DEVICE_PATH_NODE *)DevPath;
+ if (CompareGuid (&Vendor->VendorDevicePath.Guid, &gEmuThunkProtocolGuid)) {
+ CatPrint (Str, L"EmuThunk()");
+ return EFI_SUCCESS;
+ }
+ if (CompareGuid (&Vendor->VendorDevicePath.Guid, &gEmuGraphicsWindowProtocolGuid)) {
+ CatPrint (Str, L"EmuGraphics(%d)", Vendor->Instance);
+ return EFI_SUCCESS;
+ }
+ if (CompareGuid (&Vendor->VendorDevicePath.Guid, &gEfiSimpleFileSystemProtocolGuid)) {
+ CatPrint (Str, L"EmuFs(%d)", Vendor->Instance);
+ return EFI_SUCCESS;
+ }
+ if (CompareGuid (&Vendor->VendorDevicePath.Guid, &gEmuBlockIoProtocolGuid)) {
+ CatPrint (Str, L"EmuBlk(%d)", Vendor->Instance);
+ return EFI_SUCCESS;
+ }
+ if (CompareGuid (&Vendor->VendorDevicePath.Guid, &gEmuThreadThunkProtocolGuid)) {
+ CatPrint (Str, L"EmuThread()");
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Converts a text device path node to Hardware Vendor device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Hardware Vendor device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextEmuThunk (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *Str;
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Str = GetNextParamStr (&TextDeviceNode);
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH)
+ );
+ CopyGuid (&Vendor->Guid, &gEmuThunkProtocolGuid);
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Hardware Vendor device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Hardware Vendor device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextEmuThread (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *Str;
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Str = GetNextParamStr (&TextDeviceNode);
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH)
+ );
+ CopyGuid (&Vendor->Guid, &gEmuThreadThunkProtocolGuid);
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Hardware Vendor device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Hardware Vendor device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextEmuFs (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *Str;
+ EMU_VENDOR_DEVICE_PATH_NODE *Vendor;
+
+ Str = GetNextParamStr (&TextDeviceNode);
+ Vendor = (EMU_VENDOR_DEVICE_PATH_NODE *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ (UINT16) sizeof (EMU_VENDOR_DEVICE_PATH_NODE)
+ );
+ CopyGuid (&Vendor->VendorDevicePath.Guid, &gEfiSimpleFileSystemProtocolGuid);
+ Vendor->Instance = (UINT32) StrDecimalToUintn (Str);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Register the Filter function
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor executed correctly.
+
+**/
+EFI_STATUS
+EFIAPI
+DevicePathToTextLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+
+{
+ DevPathToTextSetVendorDevicePathFilter (DevPathToTextVendorLib);
+ DevicePathFromTextAddFilter (L"EmuThunk", DevPathFromTextEmuThunk);
+ DevicePathFromTextAddFilter (L"EmuThread", DevPathFromTextEmuThread);
+ DevicePathFromTextAddFilter (L"EmuFs", DevPathFromTextEmuFs);
+ return EFI_SUCCESS;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/Library/DevicePathTextLib/DevicePathTextLib.inf b/CdeEmuPkg/EmulatorPkg/Library/DevicePathTextLib/DevicePathTextLib.inf
new file mode 100644
index 00000000000..993d475b10d
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Library/DevicePathTextLib/DevicePathTextLib.inf
@@ -0,0 +1,43 @@
+## @file
+# Null DevicePathToText library.
+#
+# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DevicePathTextLib
+ FILE_GUID = DCD1F939-1732-CA4D-81B7-C757AEC84DBC
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NULL|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE
+ CONSTRUCTOR = DevicePathToTextLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ DevicePathTextLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ DevicePathLib
+
+[Protocols]
+ gEmuThunkProtocolGuid
+ gEmuGraphicsWindowProtocolGuid
+ gEfiSimpleFileSystemProtocolGuid
+ gEmuBlockIoProtocolGuid
+ gEmuThreadThunkProtocolGuid
diff --git a/CdeEmuPkg/EmulatorPkg/Library/DxeCoreTimerLib/DxeCoreTimerLib.c b/CdeEmuPkg/EmulatorPkg/Library/DxeCoreTimerLib/DxeCoreTimerLib.c
new file mode 100644
index 00000000000..710d577127c
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Library/DxeCoreTimerLib/DxeCoreTimerLib.c
@@ -0,0 +1,165 @@
+/** @file
+ A non-functional instance of the Timer Library.
+
+ Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+
+
+/**
+ Stalls the CPU for at least the given number of microseconds.
+
+ Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+ @param MicroSeconds The minimum number of microseconds to delay.
+
+ @return The value of MicroSeconds inputted.
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+ IN UINTN MicroSeconds
+ )
+{
+ return NanoSecondDelay (MicroSeconds * 1000);
+}
+
+
+/**
+ Stalls the CPU for at least the given number of nanoseconds.
+
+ Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
+
+ @param NanoSeconds The minimum number of nanoseconds to delay.
+
+ @return The value of NanoSeconds inputted.
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+ IN UINTN NanoSeconds
+ )
+{
+ gEmuThunk->Sleep (NanoSeconds);
+ return NanoSeconds;
+}
+
+
+/**
+ Retrieves the current value of a 64-bit free running performance counter.
+
+ The counter can either count up by 1 or count down by 1. If the physical
+ performance counter counts by a larger increment, then the counter values
+ must be translated. The properties of the counter can be retrieved from
+ GetPerformanceCounterProperties().
+
+ @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+ VOID
+ )
+{
+ return gEmuThunk->QueryPerformanceCounter ();
+}
+
+/**
+ Retrieves the 64-bit frequency in Hz and the range of performance counter
+ values.
+
+ If StartValue is not NULL, then the value that the performance counter starts
+ with immediately after is it rolls over is returned in StartValue. If
+ EndValue is not NULL, then the value that the performance counter end with
+ immediately before it rolls over is returned in EndValue. The 64-bit
+ frequency of the performance counter in Hz is always returned. If StartValue
+ is less than EndValue, then the performance counter counts up. If StartValue
+ is greater than EndValue, then the performance counter counts down. For
+ example, a 64-bit free running counter that counts up would have a StartValue
+ of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
+ that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
+
+ @param StartValue The value the performance counter starts with when it
+ rolls over.
+ @param EndValue The value that the performance counter ends with before
+ it rolls over.
+
+ @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+ OUT UINT64 *StartValue, OPTIONAL
+ OUT UINT64 *EndValue OPTIONAL
+ )
+{
+
+ if (StartValue != NULL) {
+ *StartValue = 0ULL;
+ }
+ if (EndValue != NULL) {
+ *EndValue = (UINT64)-1LL;
+ }
+
+ return gEmuThunk->QueryPerformanceFrequency ();
+}
+
+/**
+ Converts elapsed ticks of performance counter to time in nanoseconds.
+
+ This function converts the elapsed ticks of running performance counter to
+ time value in unit of nanoseconds.
+
+ @param Ticks The number of elapsed ticks of running performance counter.
+
+ @return The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+ IN UINT64 Ticks
+ )
+{
+ UINT64 Frequency;
+ UINT64 NanoSeconds;
+ UINT64 Remainder;
+ INTN Shift;
+
+ Frequency = GetPerformanceCounterProperties (NULL, NULL);
+
+ //
+ // Ticks
+ // Time = --------- x 1,000,000,000
+ // Frequency
+ //
+ NanoSeconds = MultU64x32 (DivU64x64Remainder (Ticks, Frequency, &Remainder), 1000000000u);
+
+ //
+ // Ensure (Remainder * 1,000,000,000) will not overflow 64-bit.
+ // Since 2^29 < 1,000,000,000 = 0x3B9ACA00 < 2^30, Remainder should < 2^(64-30) = 2^34,
+ // i.e. highest bit set in Remainder should <= 33.
+ //
+ Shift = MAX (0, HighBitSet64 (Remainder) - 33);
+ Remainder = RShiftU64 (Remainder, (UINTN) Shift);
+ Frequency = RShiftU64 (Frequency, (UINTN) Shift);
+ NanoSeconds += DivU64x64Remainder (MultU64x32 (Remainder, 1000000000u), Frequency, NULL);
+
+ return NanoSeconds;
+}
diff --git a/CdeEmuPkg/EmulatorPkg/Library/DxeCoreTimerLib/DxeCoreTimerLib.inf b/CdeEmuPkg/EmulatorPkg/Library/DxeCoreTimerLib/DxeCoreTimerLib.inf
new file mode 100644
index 00000000000..fa3e5298e09
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Library/DxeCoreTimerLib/DxeCoreTimerLib.inf
@@ -0,0 +1,39 @@
+## @file
+# NULL instance of Timer Library as a template.
+#
+# A non-functional instance of the Timer Library that can be used as a template
+# for the implementation of a functional timer library instance. This library instance can
+# also be used to test build DXE, Runtime, DXE SAL, and DXE SMM modules that require timer
+# services as well as EBC modules that require timer services.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EmuDxeCodeTimerLib
+ FILE_GUID = FB184AF4-A2F2-EE4E-8885-E81E5D8B0135
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = TimerLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION
+
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ DxeCoreTimerLib.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmulatorPkg/EmulatorPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ EmuThunkLib
+
diff --git a/CdeEmuPkg/EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.c b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.c
new file mode 100644
index 00000000000..dd41ec7263d
--- /dev/null
+++ b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.c
@@ -0,0 +1,82 @@
+/*++ @file
+
+Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include
+
+#include
+#include
+#include
+#include