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 + +EMU_THUNK_PROTOCOL *gEmuThunk = NULL; + + +/** + The constructor function caches the pointer of EMU Thunk protocol. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +DxeEmuLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + GuidHob = GetFirstGuidHob (&gEmuThunkProtocolGuid); + ASSERT (GuidHob != NULL); + + gEmuThunk = (EMU_THUNK_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob))); + ASSERT (gEmuThunk != NULL); + + return EFI_SUCCESS; +} + + +/** + 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 + ) +{ + EFI_STATUS Status; + EMU_IO_THUNK_PROTOCOL *EmuIoThunk; + + for (Status = EFI_SUCCESS, EmuIoThunk = NULL; !EFI_ERROR (Status); ) { + Status = gEmuThunk->GetNextProtocol (FALSE, &EmuIoThunk); + if (EFI_ERROR (Status)) { + break; + } + + if (EmuIoThunk->Instance == Instance) { + if (CompareGuid (EmuIoThunk->Protocol, Protocol)) { + return EmuIoThunk; + } + } + } + + return NULL; +} diff --git a/CdeEmuPkg/EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.inf b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.inf new file mode 100644 index 00000000000..170ee98f40e --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuLib/DxeEmuLib.inf @@ -0,0 +1,41 @@ +## @file +# A library to produce the global variable 'gEmuThunk' +# +# This library contains a single global variable 'gEmuThunk' along with a constructor to +# initialize that global. +# 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 = DxeEmuLib + FILE_GUID = 31479AFD-B06F-4E4A-863B-A8F7E7710778 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = EmuThunkLib + + CONSTRUCTOR = DxeEmuLibConstructor + + +[Sources] + DxeEmuLib.c + + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + HobLib + DebugLib + BaseMemoryLib + + +[Protocols] + gEmuThunkProtocolGuid # PROTOCOL ALWAYS_CONSUMED + diff --git a/CdeEmuPkg/EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.c b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.c new file mode 100644 index 00000000000..b8c8b24122a --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.c @@ -0,0 +1,97 @@ +/** @file + Provides services to perform additional actions to relocate and unload + PE/Coff image for Emu environment specific purpose such as souce level debug. + This version only works for DXE phase + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +// +// Cache of UnixThunk protocol +// +EMU_THUNK_PROTOCOL *mThunk = NULL; + + +/** + The constructor function gets the pointer of the WinNT thunk functions + It will ASSERT() if Unix thunk protocol is not installed. + + @retval EFI_SUCCESS Unix thunk protocol is found and cached. + +**/ +EFI_STATUS +EFIAPI +DxeEmuPeCoffLibExtraActionConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + + // + // Retrieve EmuThunkProtocol from GUID'ed HOB + // + GuidHob = GetFirstGuidHob (&gEmuThunkProtocolGuid); + ASSERT (GuidHob != NULL); + mThunk = (EMU_THUNK_PROTOCOL *)(*(UINTN *)(GET_GUID_HOB_DATA (GuidHob))); + ASSERT (mThunk != NULL); + + return EFI_SUCCESS; +} + +/** + Performs additional actions after a PE/COFF image has been loaded and relocated. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that has already been loaded and relocated. + +**/ +VOID +EFIAPI +PeCoffLoaderRelocateImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (mThunk != NULL) { + mThunk->PeCoffRelocateImageExtraAction (ImageContext); + } +} + + + +/** + Performs additional actions just before a PE/COFF image is unloaded. Any resources + that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that is being unloaded. + +**/ +VOID +EFIAPI +PeCoffLoaderUnloadImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (mThunk != NULL) { + mThunk->PeCoffUnloadImageExtraAction (ImageContext); + } +} diff --git a/CdeEmuPkg/EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf new file mode 100644 index 00000000000..63a01847b96 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuPeCoffExtraActionLib/DxeEmuPeCoffExtraActionLib.inf @@ -0,0 +1,42 @@ +## @file +# PeCoff extra action libary for DXE phase that run Emu emulator. +# +# Copyright (c) 2007 - 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 = DxeEmuPeCoffExtraActionLib + FILE_GUID = 68FCD487-D230-6846-95B1-5E1F2EF942C4 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeCoffExtraActionLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER + + CONSTRUCTOR = DxeEmuPeCoffLibExtraActionConstructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + DxeEmuPeCoffExtraActionLib.c + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + DebugLib + HobLib + BaseMemoryLib + +[Protocols] + gEmuThunkProtocolGuid # PROTOCOL ALWAYS_CONSUMED + diff --git a/CdeEmuPkg/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.c b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.c new file mode 100644 index 00000000000..5d06d9b15ef --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.c @@ -0,0 +1,201 @@ +/** @file + Serial Port Lib that thunks back to Emulator services to write to StdErr. + All read functions are stubed out. + + Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
+ Portions copyright (c) 2011, Apple Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + + +#include +#include +#include + + + + +/** + Initialize the serial device hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfully initialized, then return RETURN_SUCCESS. + If the serial device could not be initialized, then return RETURN_DEVICE_ERROR. + + @retval RETURN_SUCCESS The serial device was initialized. + @retval RETURN_DEVICE_ERROR The serial device could not be initialized. + +**/ +RETURN_STATUS +EFIAPI +SerialPortInitialize ( + VOID + ) +{ + return gEmuThunk->ConfigStdIn (); +} + +/** + Write data from buffer to serial device. + + Writes NumberOfBytes data bytes from Buffer to the serial device. + The number of bytes actually written to the serial device is returned. + If the return value is less than NumberOfBytes, then the write operation failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer The pointer to the data buffer to be written. + @param NumberOfBytes The number of bytes to written to the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes written to the serial device. + If this value is less than NumberOfBytes, then the read operation failed. + +**/ +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + return gEmuThunk->WriteStdOut (Buffer, NumberOfBytes); +} + + +/** + Read data from serial device and save the datas in buffer. + + Reads NumberOfBytes data bytes from a serial device into the buffer + specified by Buffer. The number of bytes actually read is returned. + If the return value is less than NumberOfBytes, then the rest operation failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer The pointer to the data buffer to store the data read from the serial device. + @param NumberOfBytes The number of bytes which will be read. + + @retval 0 Read data failed; No data is to be read. + @retval >0 The actual number of bytes read from serial device. + +**/ +UINTN +EFIAPI +SerialPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + return gEmuThunk->ReadStdIn (Buffer, NumberOfBytes); +} + +/** + Polls a serial device to see if there is any data waiting to be read. + + Polls a serial device to see if there is any data waiting to be read. + If there is data waiting to be read from the serial device, then TRUE is returned. + If there is no data waiting to be read from the serial device, then FALSE is returned. + + @retval TRUE Data is waiting to be read from the serial device. + @retval FALSE There is no data waiting to be read from the serial device. + +**/ +BOOLEAN +EFIAPI +SerialPortPoll ( + VOID + ) +{ + return gEmuThunk->PollStdIn (); +} + +/** + Sets the control bits on a serial device. + + @param Control Sets the bits of Control that are settable. + + @retval RETURN_SUCCESS The new control bits were set on the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortSetControl ( + IN UINT32 Control + ) +{ + return RETURN_UNSUPPORTED; +} + +/** + Retrieve the status of the control bits on a serial device. + + @param Control A pointer to return the current control signals from the serial device. + + @retval RETURN_SUCCESS The control bits were read from the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortGetControl ( + OUT UINT32 *Control + ) +{ + *Control = 0; + if (!SerialPortPoll ()) { + *Control = EFI_SERIAL_INPUT_BUFFER_EMPTY; + } + return RETURN_SUCCESS; +} + +/** + Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, + data bits, and stop bits on a serial device. + + @param BaudRate The requested baud rate. A BaudRate value of 0 will use the + device's default interface speed. + On output, the value actually set. + @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the + serial interface. A ReceiveFifoDepth value of 0 will use + the device's default FIFO depth. + On output, the value actually set. + @param Timeout The requested time out for a single character in microseconds. + This timeout applies to both the transmit and receive side of the + interface. A Timeout value of 0 will use the device's default time + out value. + On output, the value actually set. + @param Parity The type of parity to use on this serial device. A Parity value of + DefaultParity will use the device's default parity value. + On output, the value actually set. + @param DataBits The number of data bits to use on the serial device. A DataBits + vaule of 0 will use the device's default data bit setting. + On output, the value actually set. + @param StopBits The number of stop bits to use on this serial device. A StopBits + value of DefaultStopBits will use the device's default number of + stop bits. + On output, the value actually set. + + @retval RETURN_SUCCESS The new attributes were set on the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an unsupported value. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortSetAttributes ( + IN OUT UINT64 *BaudRate, + IN OUT UINT32 *ReceiveFifoDepth, + IN OUT UINT32 *Timeout, + IN OUT EFI_PARITY_TYPE *Parity, + IN OUT UINT8 *DataBits, + IN OUT EFI_STOP_BITS_TYPE *StopBits + ) +{ + return RETURN_UNSUPPORTED; +} + diff --git a/CdeEmuPkg/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf new file mode 100644 index 00000000000..b6db6d1dc59 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuSerialPortLib/DxeEmuSerialPortLib.inf @@ -0,0 +1,36 @@ +## @file +# Write only instance of Serial Port Library with empty functions. +# +# 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 = DxeEmuSerialPortLib + FILE_GUID = DF08A29A-F60B-E649-AA79-A1490E863A5D + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = SerialPortLib| DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVE + + +[Sources] + DxeEmuSerialPortLib.c + + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + +[LibraryClasses] + EmuThunkLib + + + + + diff --git a/CdeEmuPkg/EmulatorPkg/Library/DxeEmuStdErrSerialPortLib/DxeEmuStdErrSerialPortLib.c b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuStdErrSerialPortLib/DxeEmuStdErrSerialPortLib.c new file mode 100644 index 00000000000..abed2627454 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuStdErrSerialPortLib/DxeEmuStdErrSerialPortLib.c @@ -0,0 +1,117 @@ +/** @file + Serial Port Lib that thunks back to Emulator services to write to StdErr. + All read functions are stubed out. + + 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 + +**/ + + +#include +#include +#include + + + + +/** + Initialize the serial device hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfully initialized, then return RETURN_SUCCESS. + If the serial device could not be initialized, then return RETURN_DEVICE_ERROR. + + @retval RETURN_SUCCESS The serial device was initialized. + @retval RETURN_DEVICE_ERROR The serial device could not be initialized. + +**/ +RETURN_STATUS +EFIAPI +SerialPortInitialize ( + VOID + ) +{ + return RETURN_SUCCESS; +} + +/** + Write data from buffer to serial device. + + Writes NumberOfBytes data bytes from Buffer to the serial device. + The number of bytes actually written to the serial device is returned. + If the return value is less than NumberOfBytes, then the write operation failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer The pointer to the data buffer to be written. + @param NumberOfBytes The number of bytes to written to the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes written to the serial device. + If this value is less than NumberOfBytes, then the read operation failed. + +**/ +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + if (gEmuThunk == NULL) { + return NumberOfBytes; + } + + return gEmuThunk->WriteStdErr (Buffer, NumberOfBytes); +} + + +/** + Read data from serial device and save the datas in buffer. + + Reads NumberOfBytes data bytes from a serial device into the buffer + specified by Buffer. The number of bytes actually read is returned. + If the return value is less than NumberOfBytes, then the rest operation failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer The pointer to the data buffer to store the data read from the serial device. + @param NumberOfBytes The number of bytes which will be read. + + @retval 0 Read data failed; No data is to be read. + @retval >0 The actual number of bytes read from serial device. + +**/ +UINTN +EFIAPI +SerialPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + return 0; +} + +/** + Polls a serial device to see if there is any data waiting to be read. + + Polls a serial device to see if there is any data waiting to be read. + If there is data waiting to be read from the serial device, then TRUE is returned. + If there is no data waiting to be read from the serial device, then FALSE is returned. + + @retval TRUE Data is waiting to be read from the serial device. + @retval FALSE There is no data waiting to be read from the serial device. + +**/ +BOOLEAN +EFIAPI +SerialPortPoll ( + VOID + ) +{ + return FALSE; +} + + diff --git a/CdeEmuPkg/EmulatorPkg/Library/DxeEmuStdErrSerialPortLib/DxeEmuStdErrSerialPortLib.inf b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuStdErrSerialPortLib/DxeEmuStdErrSerialPortLib.inf new file mode 100644 index 00000000000..23af4811e79 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/DxeEmuStdErrSerialPortLib/DxeEmuStdErrSerialPortLib.inf @@ -0,0 +1,35 @@ +## @file +# Write only instance of Serial Port Library with empty functions. +# +# 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 = DxeEmuStdErrSerialPortLib + FILE_GUID = 4EED5138-C512-9E4F-AB13-149B87D40453 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = SerialPortLib| DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVE + + +[Sources] + DxeEmuStdErrSerialPortLib.c + + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + EmuThunkLib + + + + + diff --git a/CdeEmuPkg/EmulatorPkg/Library/DxeTimerLib/DxeTimerLib.c b/CdeEmuPkg/EmulatorPkg/Library/DxeTimerLib/DxeTimerLib.c new file mode 100644 index 00000000000..0a35a20992a --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/DxeTimerLib/DxeTimerLib.c @@ -0,0 +1,243 @@ +/** @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 + + +STATIC UINT64 gTimerPeriod = 0; +STATIC EFI_TIMER_ARCH_PROTOCOL *gTimerAp = NULL; +STATIC EFI_EVENT gTimerEvent = NULL; +STATIC VOID *gRegistration = NULL; + +VOID +EFIAPI +RegisterTimerArchProtocol ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + Status = gBS->LocateProtocol (&gEfiTimerArchProtocolGuid, NULL, (VOID **)&gTimerAp); + if (!EFI_ERROR (Status)) { + Status = gTimerAp->GetTimerPeriod (gTimerAp, &gTimerPeriod); + ASSERT_EFI_ERROR (Status); + + // Convert to Nanoseconds. + gTimerPeriod = MultU64x32 (gTimerPeriod, 100); + + if (gTimerEvent == NULL) { + Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &gTimerEvent); + ASSERT_EFI_ERROR (Status); + } + } +} + + + +/** + 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 + ) +{ + EFI_STATUS Status; + UINT64 HundredNanoseconds; + UINTN Index; + + if ((gTimerPeriod != 0) && + ((UINT64)NanoSeconds > gTimerPeriod) && + (EfiGetCurrentTpl () == TPL_APPLICATION)) { + // + // This stall is long, so use gBS->WaitForEvent () to yield CPU to DXE Core + // + + HundredNanoseconds = DivU64x32 (NanoSeconds, 100); + Status = gBS->SetTimer (gTimerEvent, TimerRelative, HundredNanoseconds); + ASSERT_EFI_ERROR (Status); + + Status = gBS->WaitForEvent (sizeof (gTimerEvent)/sizeof (EFI_EVENT), &gTimerEvent, &Index); + ASSERT_EFI_ERROR (Status); + + } else { + 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 (); +} + + +/** + Register for the Timer AP protocol. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +DxeTimerLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EfiCreateProtocolNotifyEvent ( + &gEfiTimerArchProtocolGuid, + TPL_CALLBACK, + RegisterTimerArchProtocol, + NULL, + &gRegistration + ); + + return EFI_SUCCESS; +} + +/** + 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/DxeTimerLib/DxeTimerLib.inf b/CdeEmuPkg/EmulatorPkg/Library/DxeTimerLib/DxeTimerLib.inf new file mode 100644 index 00000000000..02c26ae399f --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/DxeTimerLib/DxeTimerLib.inf @@ -0,0 +1,46 @@ +## @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 = EmuDxeTimerLib + FILE_GUID = 74B62391-AD0D-1B4D-8784-151404F9D538 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = TimerLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION + + CONSTRUCTOR = DxeTimerLibConstructor + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + DxeTimerLib.c + + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + EmuThunkLib + UefiLib + UefiBootServicesTableLib + +[Protocols] + gEfiTimerArchProtocolGuid diff --git a/CdeEmuPkg/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/GuardUefiMemoryAllocationLib.inf b/CdeEmuPkg/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/GuardUefiMemoryAllocationLib.inf new file mode 100644 index 00000000000..a48bc4fbcff --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/GuardUefiMemoryAllocationLib.inf @@ -0,0 +1,37 @@ +## @file +# Instance of Memory Allocation Library using EFI Boot Services. +# +# Memory Allocation Library that uses EFI Boot Services to allocate +# and free memory. Calls OS malloc to enable OS based debug tools +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = GuardUefiMemoryAllocationLib + FILE_GUID = DB290230-3EFA-064F-A317-E146925684FE + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = MemoryAllocationLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER DXE_CORE + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + MemoryAllocationLib.c + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + DebugLib + BaseMemoryLib + UefiBootServicesTableLib + EmuThunkLib diff --git a/CdeEmuPkg/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c b/CdeEmuPkg/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c new file mode 100644 index 00000000000..1636314d93d --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c @@ -0,0 +1,813 @@ +/** @file + Support routines for memory allocation routines based + on boot services for Dxe phase drivers using OS malloc. + + OS malloc is used so OS based malloc debugging tools can be used. + If a single driver links against this lib protocols from other + drivers, or EFI boot services can return a buffer that needs to + freed using the EFI scheme. This is why the gEmuThunk->Free () + can detect if the memory rang is for EFI so the right free can be + called. + + 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 + +**/ + + +#include + + +#include +#include +#include +#include +#include + +/** + Allocates one or more 4KB pages of a certain memory type. + + Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated + buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned. + If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +InternalAllocatePages ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + + if (Pages == 0) { + return NULL; + } + + return gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE); +} + +/** + Allocates one or more 4KB pages of type EfiBootServicesData. + + Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocatePages ( + IN UINTN Pages + ) +{ + return InternalAllocatePages (EfiBootServicesData, Pages); +} + +/** + Allocates one or more 4KB pages of type EfiRuntimeServicesData. + + Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimePages ( + IN UINTN Pages + ) +{ + return InternalAllocatePages (EfiRuntimeServicesData, Pages); +} + +/** + Allocates one or more 4KB pages of type EfiReservedMemoryType. + + Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedPages ( + IN UINTN Pages + ) +{ + return InternalAllocatePages (EfiReservedMemoryType, Pages); +} + +/** + Frees one or more 4KB pages that were previously allocated with one of the page allocation + functions in the Memory Allocation Library. + + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer + must have been allocated on a previous call to the page allocation services of the Memory + Allocation Library. If it is not possible to free allocated pages, then this function will + perform no actions. + + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, + then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Buffer The pointer to the buffer of pages to free. + @param Pages The number of 4 KB pages to free. + +**/ +VOID +EFIAPI +FreePages ( + IN VOID *Buffer, + IN UINTN Pages + ) +{ + EFI_STATUS Status; + + ASSERT (Pages != 0); + if (!gEmuThunk->Free (Buffer)) { + // The Free thunk will not free memory allocated in emulated EFI memory. + // The assmuption is this was allocated directly by EFI. We need this as some + // times protocols or EFI BootServices can return dynamically allocated buffers. + Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages); + ASSERT_EFI_ERROR (Status); + } +} + +/** + Allocates one or more 4KB pages of a certain memory type at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment + specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned. + If there is not enough memory at the specified alignment remaining to satisfy the request, then + NULL is returned. + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param MemoryType The type of memory to allocate. + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +InternalAllocateAlignedPages ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + IN UINTN Alignment + ) +{ + EFI_STATUS Status; + VOID *Memory; + UINTN AlignedMemory; + UINTN AlignmentMask; + UINTN UnalignedPages; + UINTN RealPages; + + // + // Alignment must be a power of two or zero. + // + ASSERT ((Alignment & (Alignment - 1)) == 0); + + if (Pages == 0) { + return NULL; + } + if (Alignment > EFI_PAGE_SIZE) { + // + // Caculate the total number of pages since alignment is larger than page size. + // + AlignmentMask = Alignment - 1; + RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment); + // + // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. + // + ASSERT (RealPages > Pages); + + Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE); + if (Memory != NULL) { + return NULL; + } + AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask; + UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory); + if (UnalignedPages > 0) { + // + // Free first unaligned page(s). + // + FreePages (Memory, UnalignedPages); + } + Memory = (VOID *) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages)); + UnalignedPages = RealPages - Pages - UnalignedPages; + if (UnalignedPages > 0) { + // + // Free last unaligned page(s). + // + FreePages (Memory, UnalignedPages); + } + } else { + // + // Do not over-allocate pages in this case. + // + Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE); + if (Memory != NULL) { + return NULL; + } + AlignedMemory = (UINTN) Memory; + } + return (VOID *) AlignedMemory; +} + +/** + Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateAlignedPages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment); +} + +/** + Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateAlignedRuntimePages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment); +} + +/** + Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateAlignedReservedPages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment); +} + +/** + Frees one or more 4KB pages that were previously allocated with one of the aligned page + allocation functions in the Memory Allocation Library. + + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer + must have been allocated on a previous call to the aligned page allocation services of the Memory + Allocation Library. If it is not possible to free allocated pages, then this function will + perform no actions. + + If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + Library, then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Buffer The pointer to the buffer of pages to free. + @param Pages The number of 4 KB pages to free. + +**/ +VOID +EFIAPI +FreeAlignedPages ( + IN VOID *Buffer, + IN UINTN Pages + ) +{ + FreePages (Buffer, Pages); +} + +/** + Allocates a buffer of a certain pool type. + + Allocates the number bytes specified by AllocationSize of a certain pool type and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param MemoryType The type of memory to allocate. + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +InternalAllocatePool ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN AllocationSize + ) +{ + return gEmuThunk->Malloc (AllocationSize); +} + +/** + Allocates a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocatePool ( + IN UINTN AllocationSize + ) +{ + return InternalAllocatePool (EfiBootServicesData, AllocationSize); +} + +/** + Allocates a buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns + a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimePool ( + IN UINTN AllocationSize + ) +{ + return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize); +} + +/** + Allocates a buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns + a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedPool ( + IN UINTN AllocationSize + ) +{ + return InternalAllocatePool (EfiReservedMemoryType, AllocationSize); +} + +/** + Allocates and zeros a buffer of a certain pool type. + + Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer + with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid + buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request, + then NULL is returned. + + @param PoolType The type of memory to allocate. + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +InternalAllocateZeroPool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN AllocationSize + ) +{ + VOID *Memory; + + Memory = InternalAllocatePool (PoolType, AllocationSize); + if (Memory != NULL) { + Memory = ZeroMem (Memory, AllocationSize); + } + return Memory; +} + +/** + Allocates and zeros a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateZeroPool ( + IN UINTN AllocationSize + ) +{ + return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize); +} + +/** + Allocates and zeros a buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimeZeroPool ( + IN UINTN AllocationSize + ) +{ + return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize); +} + +/** + Allocates and zeros a buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedZeroPool ( + IN UINTN AllocationSize + ) +{ + return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize); +} + +/** + Copies a buffer to an allocated buffer of a certain pool type. + + Allocates the number bytes specified by AllocationSize of a certain pool type, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param PoolType The type of pool to allocate. + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +InternalAllocateCopyPool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + VOID *Memory; + + ASSERT (Buffer != NULL); + ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1)); + + Memory = InternalAllocatePool (PoolType, AllocationSize); + if (Memory != NULL) { + Memory = CopyMem (Memory, Buffer, AllocationSize); + } + return Memory; +} + +/** + Copies a buffer to an allocated buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer); +} + +/** + Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimeCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer); +} + +/** + Copies a buffer to an allocated buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer); +} + +/** + Reallocates a buffer of a specified memory type. + + Allocates and zeros the number bytes specified by NewSize from memory of the type + specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param PoolType The type of pool to allocate. + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +InternalReallocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + VOID *NewBuffer; + + NewBuffer = InternalAllocateZeroPool (PoolType, NewSize); + if (NewBuffer != NULL && OldBuffer != NULL) { + CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); + FreePool (OldBuffer); + } + return NewBuffer; +} + +/** + Reallocates a buffer of type EfiBootServicesData. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocatePool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer); +} + +/** + Reallocates a buffer of type EfiRuntimeServicesData. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocateRuntimePool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer); +} + +/** + Reallocates a buffer of type EfiReservedMemoryType. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocateReservedPool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer); +} + +/** + Frees a buffer that was previously allocated with one of the pool allocation functions in the + Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + pool allocation services of the Memory Allocation Library. If it is not possible to free pool + resources, then this function will perform no actions. + + If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, + then ASSERT(). + + @param Buffer The pointer to the buffer to free. + +**/ +VOID +EFIAPI +FreePool ( + IN VOID *Buffer + ) +{ + EFI_STATUS Status; + + if (!gEmuThunk->Free (Buffer)) { + // The Free thunk will not free memory allocated in emulated EFI memory. + // The assmuption is this was allocated directly by EFI. We need this as some + // times protocols or EFI BootServices can return dynamically allocated buffers. + Status = gBS->FreePool (Buffer); + ASSERT_EFI_ERROR (Status); + } +} + diff --git a/CdeEmuPkg/EmulatorPkg/Library/KeyMapLibNull/KeyMapLibNull.c b/CdeEmuPkg/EmulatorPkg/Library/KeyMapLibNull/KeyMapLibNull.c new file mode 100644 index 00000000000..cb22a87de60 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/KeyMapLibNull/KeyMapLibNull.c @@ -0,0 +1,44 @@ +/*++ @file + +Copyright (c) 2011, Apple Inc. All rights reserved. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#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 + ) +{ + return EFI_SUCCESS; +} + +/** + 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 + ) +{ + return EFI_SUCCESS; +} diff --git a/CdeEmuPkg/EmulatorPkg/Library/KeyMapLibNull/KeyMapLibNull.inf b/CdeEmuPkg/EmulatorPkg/Library/KeyMapLibNull/KeyMapLibNull.inf new file mode 100644 index 00000000000..6d795d5c003 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/KeyMapLibNull/KeyMapLibNull.inf @@ -0,0 +1,34 @@ +## @file +# A library to produce the global variable 'gEmuThunk' +# +# This library contains a single global variable 'gEmuThunk' along with a constructor to +# initialize that global. +# 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 = KeyMapLibNull + FILE_GUID = 6B7067C7-A843-A34C-9530-48446963B740 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = KeyMapLib + +[Sources] + KeyMapLibNull.c + + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + HobLib + DebugLib + + diff --git a/CdeEmuPkg/EmulatorPkg/Library/PeiCoreServicesTablePointerLib/PeiCoreServicesTablePointerLib.inf b/CdeEmuPkg/EmulatorPkg/Library/PeiCoreServicesTablePointerLib/PeiCoreServicesTablePointerLib.inf new file mode 100644 index 00000000000..906a7e39089 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiCoreServicesTablePointerLib/PeiCoreServicesTablePointerLib.inf @@ -0,0 +1,36 @@ +## @file +# Instance of PEI Services Table Pointer Library using global variable for the table pointer. +# +# PEI Services Table Pointer Library implementation that retrieves a pointer to the +# PEI Services Table from a global variable. Not available to modules that execute from +# read-only memory. +# +# Copyright (c) 2007 - 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 = EmulatorPkgPeiCoreServicesTablePointerLib + FILE_GUID = E9A22529-44FA-3E4A-A66B-1E918E7AB26A + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeiServicesTablePointerLib|PEI_CORE + +# +# VALID_ARCHITECTURES = IA32 X64 EBC (EBC is for build only) +# + +[Sources] + PeiServicesTablePointer.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + DebugLib + diff --git a/CdeEmuPkg/EmulatorPkg/Library/PeiCoreServicesTablePointerLib/PeiServicesTablePointer.c b/CdeEmuPkg/EmulatorPkg/Library/PeiCoreServicesTablePointerLib/PeiServicesTablePointer.c new file mode 100644 index 00000000000..15988f0f44d --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiCoreServicesTablePointerLib/PeiServicesTablePointer.c @@ -0,0 +1,111 @@ +/** @file + PEI Services Table Pointer Library. + + This library is used for PEIM which does executed from flash device directly but + executed in memory. + + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +CONST EFI_PEI_SERVICES **gPeiServices; + +/** + Caches a pointer PEI Services Table. + + Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer + in a CPU specific manner as specified in the CPU binding section of the Platform Initialization + Pre-EFI Initialization Core Interface Specification. + + If PeiServicesTablePointer is NULL, then ASSERT(). + + @param PeiServicesTablePointer The address of PeiServices pointer. +**/ +VOID +EFIAPI +SetPeiServicesTablePointer ( + IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer + ) +{ + ASSERT (PeiServicesTablePointer != NULL); + gPeiServices = PeiServicesTablePointer; +} + +/** + Retrieves the cached value of the PEI Services Table pointer. + + Returns the cached value of the PEI Services Table pointer in a CPU specific manner + as specified in the CPU binding section of the Platform Initialization Pre-EFI + Initialization Core Interface Specification. + + If the cached PEI Services Table pointer is NULL, then ASSERT(). + + @return The pointer to PeiServices. + +**/ +CONST EFI_PEI_SERVICES ** +EFIAPI +GetPeiServicesTablePointer ( + VOID + ) +{ + ASSERT (gPeiServices != NULL); + return gPeiServices; +} + + +/** + The constructor function caches the pointer to PEI services. + + The constructor function caches the pointer to PEI services. + It will always return EFI_SUCCESS. + + @param FileHandle The handle of FFS header the loaded driver. + @param PeiServices The pointer to the PEI services. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +PeiServicesTablePointerLibConstructor ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + gPeiServices = PeiServices; + return EFI_SUCCESS; +} + +/** + Perform CPU specific actions required to migrate the PEI Services Table + pointer from temporary RAM to permanent RAM. + + For IA32 CPUs, the PEI Services Table pointer is stored in the 4 bytes + immediately preceding the Interrupt Descriptor Table (IDT) in memory. + For X64 CPUs, the PEI Services Table pointer is stored in the 8 bytes + immediately preceding the Interrupt Descriptor Table (IDT) in memory. + For Itanium and ARM CPUs, a the PEI Services Table Pointer is stored in + a dedicated CPU register. This means that there is no memory storage + associated with storing the PEI Services Table pointer, so no additional + migration actions are required for Itanium or ARM CPUs. + +**/ +VOID +EFIAPI +MigratePeiServicesTablePointer ( + VOID + ) +{ + // + // PEI Services Table pointer is cached in the global variable. No additional + // migration actions are required. + // + return; +} + diff --git a/CdeEmuPkg/EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c b/CdeEmuPkg/EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c new file mode 100644 index 00000000000..5e98e511c3c --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.c @@ -0,0 +1,101 @@ +/** @file + Provides services to perform additional actions to relocate and unload + PE/Coff image for Emu environment specific purpose such as souce level debug. + This version only works for PEI phase + +Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// +// Cache of UnixThunk protocol +// +EMU_THUNK_PROTOCOL *mThunk = NULL; + +/** + The function caches the pointer of the Unix thunk functions + It will ASSERT() if Unix thunk ppi is not installed. + + @retval EFI_SUCCESS WinNT thunk protocol is found and cached. + +**/ +EFI_STATUS +EFIAPI +EmuPeCoffGetThunkStucture ( + ) +{ + EMU_THUNK_PPI *ThunkPpi; + EFI_STATUS Status; + + + // + // Locate Unix ThunkPpi for retrieving standard output handle + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, + 0, + NULL, + (VOID **) &ThunkPpi + ); + ASSERT_EFI_ERROR (Status); + + EMU_MAGIC_PAGE()->Thunk = (EMU_THUNK_PROTOCOL *) ThunkPpi->Thunk (); + + return EFI_SUCCESS; +} + +/** + Performs additional actions after a PE/COFF image has been loaded and relocated. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that has already been loaded and relocated. + +**/ +VOID +EFIAPI +PeCoffLoaderRelocateImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (EMU_MAGIC_PAGE()->Thunk == NULL) { + EmuPeCoffGetThunkStucture (); + } + EMU_MAGIC_PAGE()->Thunk->PeCoffRelocateImageExtraAction (ImageContext); + } + + +/** + Performs additional actions just before a PE/COFF image is unloaded. Any resources + that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that is being unloaded. + +**/ +VOID +EFIAPI +PeCoffLoaderUnloadImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (EMU_MAGIC_PAGE()->Thunk == NULL) { + EmuPeCoffGetThunkStucture (); + } + EMU_MAGIC_PAGE()->Thunk->PeCoffUnloadImageExtraAction (ImageContext); +} diff --git a/CdeEmuPkg/EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf b/CdeEmuPkg/EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf new file mode 100644 index 00000000000..286046a6952 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiEmuPeCoffExtraActionLib/PeiEmuPeCoffExtraActionLib.inf @@ -0,0 +1,43 @@ +## @file +# PeCoff extra action libary for Pei phase that run Emu emulator. +# +# Lib to provide memory journal status code reporting Routines +# Copyright (c) 2007 - 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 = PeiEmuPeCoffExtraActionLib + FILE_GUID = 79C4E72A-730B-F040-8129-95877B3A97A8 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeCoffExtraActionLib|PEI_CORE PEIM + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + PeiEmuPeCoffExtraActionLib.c + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + BaseLib + PeiServicesLib + DebugLib + +[Ppis] + gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED + +[Pcd] + gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage diff --git a/CdeEmuPkg/EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.c b/CdeEmuPkg/EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.c new file mode 100644 index 00000000000..db243235efb --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.c @@ -0,0 +1,291 @@ +/*++ @file + +Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PiPei.h" +#include +#include +#include +#include + +#include +#include + + + +/** + Retrieves and returns a pointer to the entry point to a PE/COFF image that has been loaded + into system memory with the PE/COFF Loader Library functions. + + Retrieves the entry point to the PE/COFF image specified by Pe32Data and returns this entry + point in EntryPoint. If the entry point could not be retrieved from the PE/COFF image, then + return RETURN_INVALID_PARAMETER. Otherwise return RETURN_SUCCESS. + If Pe32Data is NULL, then ASSERT(). + If EntryPoint is NULL, then ASSERT(). + + @param Pe32Data The pointer to the PE/COFF image that is loaded in system memory. + @param EntryPoint The pointer to entry point to the PE/COFF image to return. + + @retval RETURN_SUCCESS EntryPoint was returned. + @retval RETURN_INVALID_PARAMETER The entry point could not be found in the PE/COFF image. + +**/ +RETURN_STATUS +EFIAPI +PeCoffLoaderGetEntryPoint ( + IN VOID *Pe32Data, + IN OUT VOID **EntryPoint + ) +{ + EMU_THUNK_PPI *ThunkPpi; + EFI_STATUS Status; + EMU_THUNK_PROTOCOL *Thunk; + + // + // Locate EmuThunkPpi for retrieving standard output handle + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, + 0, + NULL, + (VOID **) &ThunkPpi + ); + ASSERT_EFI_ERROR (Status); + + Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk (); + + return Thunk->PeCoffGetEntryPoint (Pe32Data, EntryPoint); +} + +/** + Returns the machine type of PE/COFF image. + This is copied from MDE BasePeCoffGetEntryPointLib, the code should be sync with it. + The reason is Emu package needs to load the image to memory to support source + level debug. + + + @param Pe32Data Pointer to a PE/COFF header + + @return Machine type or zero if not a valid iamge + +**/ +UINT16 +EFIAPI +PeCoffLoaderGetMachineType ( + IN VOID *Pe32Data + ) +{ + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + EFI_IMAGE_DOS_HEADER *DosHdr; + + ASSERT (Pe32Data != NULL); + + DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; + if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); + + } else { + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(Pe32Data); + } + + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + return Hdr.Te->Machine; + } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + return Hdr.Pe32->FileHeader.Machine; + } + + return 0x0000; +} + +/** + Returns a pointer to the PDB file name for a PE/COFF image that has been + loaded into system memory with the PE/COFF Loader Library functions. + + Returns the PDB file name for the PE/COFF image specified by Pe32Data. If + the PE/COFF image specified by Pe32Data is not a valid, then NULL is + returned. If the PE/COFF image specified by Pe32Data does not contain a + debug directory entry, then NULL is returned. If the debug directory entry + in the PE/COFF image specified by Pe32Data does not contain a PDB file name, + then NULL is returned. + If Pe32Data is NULL, then ASSERT(). + + @param Pe32Data Pointer to the PE/COFF image that is loaded in system + memory. + + @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL + if it cannot be retrieved. + +**/ +VOID * +EFIAPI +PeCoffLoaderGetPdbPointer ( + IN VOID *Pe32Data + ) +{ + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; + EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; + UINTN DirCount; + VOID *CodeViewEntryPointer; + INTN TEImageAdjust; + UINT32 NumberOfRvaAndSizes; + UINT16 Magic; + + ASSERT (Pe32Data != NULL); + + TEImageAdjust = 0; + DirectoryEntry = NULL; + DebugEntry = NULL; + NumberOfRvaAndSizes = 0; + + DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; + if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + // + // DOS image header is present, so read the PE header after the DOS image header. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); + } else { + // + // DOS image header is not present, so PE header is at the image base. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; + } + + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) { + DirectoryEntry = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG]; + TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize; + DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te + + Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress + + TEImageAdjust); + } + } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + // + // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic. + // It is due to backward-compatibility, for some system might + // generate PE32+ image with PE32 Magic. + // + switch (Hdr.Pe32->FileHeader.Machine) { + case EFI_IMAGE_MACHINE_IA32: + // + // Assume PE32 image with IA32 Machine field. + // + Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; + break; + case EFI_IMAGE_MACHINE_X64: + case EFI_IMAGE_MACHINE_IA64: + // + // Assume PE32+ image with X64 or IA64 Machine field + // + Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; + break; + default: + // + // For unknow Machine field, use Magic in optional Header + // + Magic = Hdr.Pe32->OptionalHeader.Magic; + } + + if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + // + // Use PE32 offset get Debug Directory Entry + // + NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes; + DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); + DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress); + } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + // + // Use PE32+ offset get Debug Directory Entry + // + NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes; + DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); + DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) Pe32Data + DirectoryEntry->VirtualAddress); + } + + if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { + DirectoryEntry = NULL; + DebugEntry = NULL; + } + } else { + return NULL; + } + + if (DebugEntry == NULL || DirectoryEntry == NULL) { + return NULL; + } + + for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) { + if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { + if (DebugEntry->SizeOfData > 0) { + CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + ((UINTN)Pe32Data) + (UINTN)TEImageAdjust); + switch (* (UINT32 *) CodeViewEntryPointer) { + case CODEVIEW_SIGNATURE_NB10: + return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)); + case CODEVIEW_SIGNATURE_RSDS: + return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY)); + case CODEVIEW_SIGNATURE_MTOC: + return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY)); + default: + break; + } + } + } + } + + return NULL; +} + + +/** + Returns the size of the PE/COFF headers + + Returns the size of the PE/COFF header specified by Pe32Data. + If Pe32Data is NULL, then ASSERT(). + + @param Pe32Data Pointer to the PE/COFF image that is loaded in system + memory. + + @return Size of PE/COFF header in bytes or zero if not a valid image. + +**/ +UINT32 +EFIAPI +PeCoffGetSizeOfHeaders ( + IN VOID *Pe32Data + ) +{ + EFI_IMAGE_DOS_HEADER *DosHdr; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + UINTN SizeOfHeaders; + + ASSERT (Pe32Data != NULL); + + DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; + if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { + // + // DOS image header is present, so read the PE header after the DOS image header. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); + } else { + // + // DOS image header is not present, so PE header is at the image base. + // + Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; + } + + if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { + SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize; + } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { + SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders; + } else { + SizeOfHeaders = 0; + } + + return (UINT32) SizeOfHeaders; +} + diff --git a/CdeEmuPkg/EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf b/CdeEmuPkg/EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf new file mode 100644 index 00000000000..5d0dbd2fd8e --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiEmuPeCoffGetEntryPointLib/PeiEmuPeCoffGetEntryPointLib.inf @@ -0,0 +1,44 @@ +## @file +# Component description file for the EdkNt32PeiPeCoffGetEntryPointLib library. +# +# PeCoffGetEntryPointLib library class for NT32 instance implemented by use NTPeiLoadFile PPI. +# 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 = PeiEmuPeCoffGetEntryPointLib + FILE_GUID = 1CBED347-7DE6-BC48-AC68-3758598124D2 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeCoffGetEntryPointLib + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + PeiEmuPeCoffGetEntryPointLib.c + + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + + +[LibraryClasses] + PeiServicesLib + DebugLib + + +[Ppis] + gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED + diff --git a/CdeEmuPkg/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.c b/CdeEmuPkg/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.c new file mode 100644 index 00000000000..b4d9672a19d --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.c @@ -0,0 +1,133 @@ +/** @file + Serial Port Lib that thunks back to Emulator services to write to StdErr. + All read functions are stubed out. There is no constructor so this lib can + be linked with PEI Core. + + 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 + +**/ + + +#include +#include +#include + +#include +#include + + + +/** + Initialize the serial device hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfully initialized, then return RETURN_SUCCESS. + If the serial device could not be initialized, then return RETURN_DEVICE_ERROR. + + @retval RETURN_SUCCESS The serial device was initialized. + @retval RETURN_DEVICE_ERROR The serial device could not be initialized. + +**/ +RETURN_STATUS +EFIAPI +SerialPortInitialize ( + VOID + ) +{ + return RETURN_SUCCESS; +} + +/** + Write data from buffer to serial device. + + Writes NumberOfBytes data bytes from Buffer to the serial device. + The number of bytes actually written to the serial device is returned. + If the return value is less than NumberOfBytes, then the write operation failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer The pointer to the data buffer to be written. + @param NumberOfBytes The number of bytes to written to the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes written to the serial device. + If this value is less than NumberOfBytes, then the read operation failed. + +**/ +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + EMU_THUNK_PPI *ThunkPpi; + EFI_STATUS Status; + EMU_THUNK_PROTOCOL *Thunk; + + // + // Locate EmuThunkPpi for retrieving standard output handle + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, + 0, + NULL, + (VOID **) &ThunkPpi + ); + if (!EFI_ERROR (Status)) { + Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk (); + return Thunk->WriteStdErr (Buffer, NumberOfBytes); + } + + return 0; +} + + +/** + Read data from serial device and save the datas in buffer. + + Reads NumberOfBytes data bytes from a serial device into the buffer + specified by Buffer. The number of bytes actually read is returned. + If the return value is less than NumberOfBytes, then the rest operation failed. + If Buffer is NULL, then ASSERT(). + If NumberOfBytes is zero, then return 0. + + @param Buffer The pointer to the data buffer to store the data read from the serial device. + @param NumberOfBytes The number of bytes which will be read. + + @retval 0 Read data failed; No data is to be read. + @retval >0 The actual number of bytes read from serial device. + +**/ +UINTN +EFIAPI +SerialPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + return 0; +} + +/** + Polls a serial device to see if there is any data waiting to be read. + + Polls a serial device to see if there is any data waiting to be read. + If there is data waiting to be read from the serial device, then TRUE is returned. + If there is no data waiting to be read from the serial device, then FALSE is returned. + + @retval TRUE Data is waiting to be read from the serial device. + @retval FALSE There is no data waiting to be read from the serial device. + +**/ +BOOLEAN +EFIAPI +SerialPortPoll ( + VOID + ) +{ + return FALSE; +} + diff --git a/CdeEmuPkg/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf b/CdeEmuPkg/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf new file mode 100644 index 00000000000..3bee75588e2 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiEmuSerialPortLib/PeiEmuSerialPortLib.inf @@ -0,0 +1,41 @@ +## @file +# Write only instance of Serial Port Library with empty functions. +# +# 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 = PeiEmuSerialPortLibNull + FILE_GUID = 76003416-0373-4C3C-BC4C-87E367FD4BD1 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = SerialPortLib| PEI_CORE PEIM SEC + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + PeiEmuSerialPortLib.c + + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + +[LibraryClasses] + PeiServicesLib + +[Ppis] + gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED + + + + diff --git a/CdeEmuPkg/EmulatorPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c b/CdeEmuPkg/EmulatorPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c new file mode 100644 index 00000000000..6068fb4fc8c --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c @@ -0,0 +1,156 @@ +/** @file + PEI Services Table Pointer Library. + + This library is used for PEIM which does executed from flash device directly but + executed in memory. + + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ Portiions copyrigth (c) 2011, Apple Inc. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +#include + + +CONST EFI_PEI_SERVICES **gPeiServices = NULL; + +/** + Caches a pointer PEI Services Table. + + Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer + in a CPU specific manner as specified in the CPU binding section of the Platform Initialization + Pre-EFI Initialization Core Interface Specification. + + If PeiServicesTablePointer is NULL, then ASSERT(). + + @param PeiServicesTablePointer The address of PeiServices pointer. +**/ +VOID +EFIAPI +SetPeiServicesTablePointer ( + IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer + ) +{ + ASSERT (PeiServicesTablePointer != NULL); + ASSERT (*PeiServicesTablePointer != NULL); + gPeiServices = PeiServicesTablePointer; +} + +/** + Retrieves the cached value of the PEI Services Table pointer. + + Returns the cached value of the PEI Services Table pointer in a CPU specific manner + as specified in the CPU binding section of the Platform Initialization Pre-EFI + Initialization Core Interface Specification. + + If the cached PEI Services Table pointer is NULL, then ASSERT(). + + @return The pointer to PeiServices. + +**/ +CONST EFI_PEI_SERVICES ** +EFIAPI +GetPeiServicesTablePointer ( + VOID + ) +{ + ASSERT (gPeiServices != NULL); + ASSERT (*gPeiServices != NULL); + return gPeiServices; +} + + + +/** + Notification service to be called when gEmuThunkPpiGuid is installed. + + @param PeiServices Indirect reference to the PEI Services Table. + @param NotifyDescriptor Address of the notification descriptor data structure. Type + EFI_PEI_NOTIFY_DESCRIPTOR is defined above. + @param Ppi Address of the PPI that was installed. + + @retval EFI_STATUS This function will install a PPI to PPI database. The status + code will be the code for (*PeiServices)->InstallPpi. + +**/ +EFI_STATUS +EFIAPI +PeiServicesTablePointerNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + gPeiServices = (CONST EFI_PEI_SERVICES **)PeiServices; + + return EFI_SUCCESS; +} + + +EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnThunkList = { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiMemoryDiscoveredPpiGuid, + PeiServicesTablePointerNotifyCallback +}; + + +/** + Constructor register notification on when PPI updates. If PPI is + alreay installed registering the notify will cause the handle to + run. + + @param FileHandle The handle of FFS header the loaded driver. + @param PeiServices The pointer to the PEI services. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +PeiServicesTablePointerLibConstructor ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + gPeiServices = (CONST EFI_PEI_SERVICES **)PeiServices; + + // register to be told when PeiServices pointer is updated + Status = (*PeiServices)->NotifyPpi (PeiServices, &mNotifyOnThunkList); + ASSERT_EFI_ERROR (Status); + return Status; +} + +/** + Perform CPU specific actions required to migrate the PEI Services Table + pointer from temporary RAM to permanent RAM. + + For IA32 CPUs, the PEI Services Table pointer is stored in the 4 bytes + immediately preceding the Interrupt Descriptor Table (IDT) in memory. + For X64 CPUs, the PEI Services Table pointer is stored in the 8 bytes + immediately preceding the Interrupt Descriptor Table (IDT) in memory. + For Itanium and ARM CPUs, a the PEI Services Table Pointer is stored in + a dedicated CPU register. This means that there is no memory storage + associated with storing the PEI Services Table pointer, so no additional + migration actions are required for Itanium or ARM CPUs. + +**/ +VOID +EFIAPI +MigratePeiServicesTablePointer ( + VOID + ) +{ + // + // PEI Services Table pointer is cached in the global variable. No additional + // migration actions are required. + // + return; +} + diff --git a/CdeEmuPkg/EmulatorPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf b/CdeEmuPkg/EmulatorPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf new file mode 100644 index 00000000000..819c4c9702c --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf @@ -0,0 +1,41 @@ +## @file +# Instance of PEI Services Table Pointer Library using global variable for the table pointer. +# +# PEI Services Table Pointer Library implementation that retrieves a pointer to the +# PEI Services Table from a global variable. Not available to modules that execute from +# read-only memory. +# +# Copyright (c) 2007 - 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 = EmulatorPkgPeiServicesTablePointerLib + FILE_GUID = 5FD8B4ED-D66F-C144-9953-AC557C649925 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeiServicesTablePointerLib|PEIM + + CONSTRUCTOR = PeiServicesTablePointerLibConstructor + +# +# VALID_ARCHITECTURES = IA32 X64 EBC (EBC is for build only) +# + +[Sources] + PeiServicesTablePointer.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + DebugLib + +[Ppis] + gEfiPeiMemoryDiscoveredPpiGuid + diff --git a/CdeEmuPkg/EmulatorPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointer.c b/CdeEmuPkg/EmulatorPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointer.c new file mode 100644 index 00000000000..e885096810d --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointer.c @@ -0,0 +1,95 @@ +/** @file + PEI Services Table Pointer Library. + + Store PEI Services Table pointer via gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage. + This emulates a platform SRAM. The PI mechaism does not work in the emulator due to + lack of privledge. + + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ Portiions copyrigth (c) 2011, Apple Inc. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + + +/** + Caches a pointer PEI Services Table. + + Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer + in a CPU specific manner as specified in the CPU binding section of the Platform Initialization + Pre-EFI Initialization Core Interface Specification. + + If PeiServicesTablePointer is NULL, then ASSERT(). + + @param PeiServicesTablePointer The address of PeiServices pointer. +**/ +VOID +EFIAPI +SetPeiServicesTablePointer ( + IN CONST EFI_PEI_SERVICES ** PeiServicesTablePointer + ) +{ + ASSERT (PeiServicesTablePointer != NULL); + ASSERT (*PeiServicesTablePointer != NULL); + EMU_MAGIC_PAGE()->PeiServicesTablePointer = PeiServicesTablePointer; +} + +/** + Retrieves the cached value of the PEI Services Table pointer. + + Returns the cached value of the PEI Services Table pointer in a CPU specific manner + as specified in the CPU binding section of the Platform Initialization Pre-EFI + Initialization Core Interface Specification. + + If the cached PEI Services Table pointer is NULL, then ASSERT(). + + @return The pointer to PeiServices. + +**/ +CONST EFI_PEI_SERVICES ** +EFIAPI +GetPeiServicesTablePointer ( + VOID + ) +{ + CONST EFI_PEI_SERVICES **PeiServicesTablePointer; + + PeiServicesTablePointer = EMU_MAGIC_PAGE()->PeiServicesTablePointer; + ASSERT (PeiServicesTablePointer != NULL); + ASSERT (*PeiServicesTablePointer != NULL); + return PeiServicesTablePointer; +} + +/** + Perform CPU specific actions required to migrate the PEI Services Table + pointer from temporary RAM to permanent RAM. + + For IA32 CPUs, the PEI Services Table pointer is stored in the 4 bytes + immediately preceding the Interrupt Descriptor Table (IDT) in memory. + For X64 CPUs, the PEI Services Table pointer is stored in the 8 bytes + immediately preceding the Interrupt Descriptor Table (IDT) in memory. + For Itanium and ARM CPUs, a the PEI Services Table Pointer is stored in + a dedicated CPU register. This means that there is no memory storage + associated with storing the PEI Services Table pointer, so no additional + migration actions are required for Itanium or ARM CPUs. + +**/ +VOID +EFIAPI +MigratePeiServicesTablePointer ( + VOID + ) +{ + // + // PEI Services Table pointer is cached in SRAM. No additional + // migration actions are required. + // + return; +} + + diff --git a/CdeEmuPkg/EmulatorPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointerLibMagicPage.inf b/CdeEmuPkg/EmulatorPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointerLibMagicPage.inf new file mode 100644 index 00000000000..fe3dcf393a9 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiServicesTablePointerLibMagicPage/PeiServicesTablePointerLibMagicPage.inf @@ -0,0 +1,39 @@ +## @file +# PEI Services Table Pointer Library. +# +# Store PEI Services Table pointer via gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage. +# This emulates a platform SRAM. The PI mechaism does not work in the emulator due to +# lack of privledge. +# +# Copyright (c) 2007 - 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 = EmulatorPkgPeiServicesTablePointerLib + FILE_GUID = 7488FC06-370A-1C41-B05C-7395559A535A + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeiServicesTablePointerLib|PEIM PEI_CORE SEC + +# +# VALID_ARCHITECTURES = IA32 X64 EBC (EBC is for build only) +# + +[Sources] + PeiServicesTablePointer.c + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + DebugLib + +[Pcd] + gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage diff --git a/CdeEmuPkg/EmulatorPkg/Library/PeiTimerLib/PeiTimerLib.c b/CdeEmuPkg/EmulatorPkg/Library/PeiTimerLib/PeiTimerLib.c new file mode 100644 index 00000000000..43bf57691b2 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiTimerLib/PeiTimerLib.c @@ -0,0 +1,213 @@ +/** @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 + +/** + 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 + ) +{ + EMU_THUNK_PPI *ThunkPpi; + EFI_STATUS Status; + EMU_THUNK_PROTOCOL *Thunk; + + // + // Locate EmuThunkPpi for + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, + 0, + NULL, + (VOID **) &ThunkPpi + ); + if (!EFI_ERROR (Status)) { + Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk (); + Thunk->Sleep (NanoSeconds * 100); + return NanoSeconds; + } + + return 0; +} + +/** + 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 + ) +{ + EMU_THUNK_PPI *ThunkPpi; + EFI_STATUS Status; + EMU_THUNK_PROTOCOL *Thunk; + + // + // Locate EmuThunkPpi for + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, + 0, + NULL, + (VOID **) &ThunkPpi + ); + if (!EFI_ERROR (Status)) { + Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk (); + return Thunk->QueryPerformanceCounter (); + } + + return 0; +} + +/** + 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 + ) +{ + EMU_THUNK_PPI *ThunkPpi; + EFI_STATUS Status; + EMU_THUNK_PROTOCOL *Thunk; + + // + // Locate EmuThunkPpi for + // + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, + 0, + NULL, + (VOID **) &ThunkPpi + ); + if (!EFI_ERROR (Status)) { + if (StartValue != NULL) { + *StartValue = 0ULL; + } + if (EndValue != NULL) { + *EndValue = (UINT64)-1LL; + } + + Thunk = (EMU_THUNK_PROTOCOL *)ThunkPpi->Thunk (); + return Thunk->QueryPerformanceFrequency (); + } + + return 0; +} + +/** + 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/PeiTimerLib/PeiTimerLib.inf b/CdeEmuPkg/EmulatorPkg/Library/PeiTimerLib/PeiTimerLib.inf new file mode 100644 index 00000000000..85ec40cf60c --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PeiTimerLib/PeiTimerLib.inf @@ -0,0 +1,42 @@ +## @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 = EmuPeiTimerLib + FILE_GUID = 6ABE5FDC-AE4B-474E-8E52-9546C96AE536 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = TimerLib|PEIM PEI_CORE SEC + + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + PeiTimerLib.c + + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + DebugLib + PeiServicesLib + +[Ppis] + gEmuThunkPpiGuid diff --git a/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBm.c b/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBm.c new file mode 100644 index 00000000000..f49a6dc2168 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBm.c @@ -0,0 +1,459 @@ +/*++ @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 "PlatformBm.h" + +EFI_GUID mBootMenuFile = { + 0xEEC25BDC, 0x67F2, 0x4D95, { 0xB1, 0xD5, 0xF8, 0x1B, 0x20, 0x39, 0xD1, 0x1D } +}; + +/** + Initialize the "Setup" variable. +**/ +VOID +SetupVariableInit ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Size; + EMU_SYSTEM_CONFIGURATION SystemConfigData; + + Size = sizeof (SystemConfigData); + Status = gRT->GetVariable ( + L"Setup", + &gEmuSystemConfigGuid, + NULL, + &Size, + (VOID *) &SystemConfigData + ); + + if (EFI_ERROR (Status)) { + // + // SetupVariable is corrupt + // + SystemConfigData.ConOutRow = PcdGet32 (PcdConOutColumn); + SystemConfigData.ConOutColumn = PcdGet32 (PcdConOutRow); + + Status = gRT->SetVariable ( + L"Setup", + &gEmuSystemConfigGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (SystemConfigData), + (VOID *) &SystemConfigData + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to save Setup Variable to non-volatile storage, Status = %r\n", Status)); + } + } +} + +EFI_DEVICE_PATH * +FvFilePath ( + EFI_GUID *FileGuid + ) +{ + + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; + + EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); + + Status = gBS->HandleProtocol ( + gImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &LoadedImage + ); + ASSERT_EFI_ERROR (Status); + return AppendDevicePathNode ( + DevicePathFromHandle (LoadedImage->DeviceHandle), + (EFI_DEVICE_PATH_PROTOCOL *) &FileNode + ); +} + +/** + Create one boot option for BootManagerMenuApp. + + @param FileGuid Input file guid for the BootManagerMenuApp. + @param Description Description of the BootManagerMenuApp boot option. + @param Position Position of the new load option to put in the ****Order variable. + @param IsBootCategory Whether this is a boot category. + + + @retval OptionNumber Return the option number info. + +**/ +UINTN +RegisterBootManagerMenuAppBootOption ( + EFI_GUID *FileGuid, + CHAR16 *Description, + UINTN Position, + BOOLEAN IsBootCategory + ) +{ + EFI_STATUS Status; + EFI_BOOT_MANAGER_LOAD_OPTION NewOption; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN OptionNumber; + + DevicePath = FvFilePath (FileGuid); + Status = EfiBootManagerInitializeLoadOption ( + &NewOption, + LoadOptionNumberUnassigned, + LoadOptionTypeBoot, + IsBootCategory ? LOAD_OPTION_ACTIVE : LOAD_OPTION_CATEGORY_APP, + Description, + DevicePath, + NULL, + 0 + ); + ASSERT_EFI_ERROR (Status); + FreePool (DevicePath); + + Status = EfiBootManagerAddLoadOptionVariable (&NewOption, Position); + ASSERT_EFI_ERROR (Status); + + OptionNumber = NewOption.OptionNumber; + + EfiBootManagerFreeLoadOption (&NewOption); + + return OptionNumber; +} + +/** + Check if it's a Device Path pointing to BootManagerMenuApp. + + @param DevicePath Input device path. + + @retval TRUE The device path is BootManagerMenuApp File Device Path. + @retval FALSE The device path is NOT BootManagerMenuApp File Device Path. +**/ +BOOLEAN +IsBootManagerMenuAppFilePath ( + EFI_DEVICE_PATH_PROTOCOL *DevicePath +) +{ + EFI_HANDLE FvHandle; + VOID *NameGuid; + EFI_STATUS Status; + + Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, &DevicePath, &FvHandle); + if (!EFI_ERROR (Status)) { + NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((CONST MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePath); + if (NameGuid != NULL) { + return CompareGuid (NameGuid, &mBootMenuFile); + } + } + + return FALSE; +} + +/** + Return the boot option number to the BootManagerMenuApp. + + If not found it in the current boot option, create a new one. + + @retval OptionNumber Return the boot option number to the BootManagerMenuApp. + +**/ +UINTN +GetBootManagerMenuAppOption ( + VOID + ) +{ + UINTN BootOptionCount; + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN Index; + UINTN OptionNumber; + + OptionNumber = 0; + + BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot); + + for (Index = 0; Index < BootOptionCount; Index++) { + if (IsBootManagerMenuAppFilePath (BootOptions[Index].FilePath)) { + OptionNumber = BootOptions[Index].OptionNumber; + break; + } + } + + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); + + if (Index >= BootOptionCount) { + // + // If not found the BootManagerMenuApp, create it. + // + OptionNumber = (UINT16) RegisterBootManagerMenuAppBootOption (&mBootMenuFile, L"UEFI BootManagerMenuApp", (UINTN) -1, FALSE); + } + + return OptionNumber; +} + +/** + Platform Bds init. Include the platform firmware vendor, revision + and so crc check. +**/ +VOID +EFIAPI +PlatformBootManagerBeforeConsole ( + VOID + ) +{ + UINTN Index; + + SetupVariableInit (); + + EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid); + + Index = 0; + while (gPlatformConsole[Index].DevicePath != NULL) { + // + // Update the console variable with the connect type + // + if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) { + EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformConsole[Index].DevicePath, NULL); + } + + if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) { + EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformConsole[Index].DevicePath, NULL); + } + + if ((gPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) { + EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformConsole[Index].DevicePath, NULL); + } + + Index++; + } +} + +/** + Connect with predefined platform connect sequence, + the OEM/IBV can customize with their own connect sequence. +**/ +VOID +PlatformBdsConnectSequence ( + VOID + ) +{ + // + // Just use the simple policy to connect all devices + // + EfiBootManagerConnectAll (); +} + +/** + Perform the platform diagnostic, such like test memory. OEM/IBV also + can customize this fuction to support specific platform diagnostic. + + @param MemoryTestLevel The memory test intensive level + @param QuietBoot Indicate if need to enable the quiet boot +**/ +VOID +PlatformBdsDiagnostics ( + IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel, + IN BOOLEAN QuietBoot + ) +{ + EFI_STATUS Status; + + // + // Here we can decide if we need to show + // the diagnostics screen + // + if (QuietBoot) { + BootLogoEnableLogo (); + + // + // Perform system diagnostic + // + Status = PlatformBootManagerMemoryTest (MemoryTestLevel); + if (EFI_ERROR (Status)) { + BootLogoDisableLogo (); + } + + return; + } + + // + // Perform system diagnostic + // + PlatformBootManagerMemoryTest (MemoryTestLevel); +} + +/** + Register the static boot options. +**/ +VOID +PlatformBdsRegisterStaticBootOptions ( + VOID + ) +{ + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL White; + EFI_INPUT_KEY Enter; + EFI_INPUT_KEY F2; + EFI_INPUT_KEY F7; + EFI_BOOT_MANAGER_LOAD_OPTION BootOption; + UINTN OptionNumber; + + Black.Blue = Black.Green = Black.Red = Black.Reserved = 0; + White.Blue = White.Green = White.Red = White.Reserved = 0xFF; + + // + // Register ENTER as CONTINUE key + // + Enter.ScanCode = SCAN_NULL; + Enter.UnicodeChar = CHAR_CARRIAGE_RETURN; + EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL); + // + // Map F2 to Boot Manager Menu + // + F2.ScanCode = SCAN_F2; + F2.UnicodeChar = CHAR_NULL; + EfiBootManagerGetBootManagerMenu (&BootOption); + EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL); + + // + // 3. Boot Device List menu + // + F7.ScanCode = SCAN_F7; + F7.UnicodeChar = CHAR_NULL; + OptionNumber = GetBootManagerMenuAppOption (); + EfiBootManagerAddKeyOptionVariable (NULL, (UINT16)OptionNumber, 0, &F7, NULL); + + PrintXY (10, 10, &White, &Black, L"F2 to enter Setup. "); + PrintXY (10, 30, &White, &Black, L"F7 to enter Boot Manager Menu."); + PrintXY (10, 50, &White, &Black, L"Enter to boot directly."); +} + +/** + Returns the priority number. + + @param BootOption +**/ +UINTN +BootOptionPriority ( + CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOption + ) +{ + // + // Make sure Shell is first + // + if (StrCmp (BootOption->Description, L"UEFI Shell") == 0) { + return 0; + } + return 100; +} + +INTN +EFIAPI +CompareBootOption ( + CONST EFI_BOOT_MANAGER_LOAD_OPTION *Left, + CONST EFI_BOOT_MANAGER_LOAD_OPTION *Right + ) +{ + return BootOptionPriority (Left) - BootOptionPriority (Right); +} + +/** + Do the platform specific action after the console is connected. + + Such as: + Dynamically switch output mode; + Signal console ready platform customized event; + Run diagnostics like memory testing; + Connect certain devices; + Dispatch aditional option roms. +**/ +VOID +EFIAPI +PlatformBootManagerAfterConsole ( + VOID + ) +{ + + // + // Go the different platform policy with different boot mode + // Notes: this part code can be change with the table policy + // + switch (GetBootModeHob ()) { + + case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES: + case BOOT_WITH_MINIMAL_CONFIGURATION: + PlatformBdsDiagnostics (IGNORE, TRUE); + + // + // Perform some platform specific connect sequence + // + PlatformBdsConnectSequence (); + break; + + case BOOT_IN_RECOVERY_MODE: + PlatformBdsDiagnostics (EXTENSIVE, FALSE); + break; + + case BOOT_WITH_FULL_CONFIGURATION: + case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS: + case BOOT_WITH_DEFAULT_SETTINGS: + default: + PlatformBdsDiagnostics (IGNORE, TRUE); + PlatformBdsRegisterStaticBootOptions (); + PlatformBdsConnectSequence (); + EfiBootManagerRefreshAllBootOption (); + EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, (SORT_COMPARE)CompareBootOption); + break; + } +} + +/** + This function is called each second during the boot manager waits the timeout. + + @param TimeoutRemain The remaining timeout. +**/ +VOID +EFIAPI +PlatformBootManagerWaitCallback ( + UINT16 TimeoutRemain + ) +{ + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White; + UINT16 Timeout; + + Timeout = PcdGet16 (PcdPlatformBootTimeOut); + + Black.Raw = 0x00000000; + White.Raw = 0x00FFFFFF; + + BootLogoUpdateProgress ( + White.Pixel, + Black.Pixel, + L"Start boot option", + White.Pixel, + (Timeout - TimeoutRemain) * 100 / Timeout, + 0 + ); +} + +/** + The function is called when no boot option could be launched, + including platform recovery options and options pointing to applications + built into firmware volumes. + + If this function returns, BDS attempts to enter an infinite loop. +**/ +VOID +EFIAPI +PlatformBootManagerUnableToBoot ( + VOID + ) +{ + return; +} + diff --git a/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBm.h b/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBm.h new file mode 100644 index 00000000000..ed425a916e1 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBm.h @@ -0,0 +1,92 @@ +/*++ @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 + +**/ + +#ifndef _PLATFORM_BM_H +#define _PLATFORM_BM_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CONSOLE_OUT 0x00000001 +#define STD_ERROR 0x00000002 +#define CONSOLE_IN 0x00000004 +#define CONSOLE_ALL (CONSOLE_OUT | CONSOLE_IN | STD_ERROR) + +typedef struct { + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN ConnectType; +} BDS_CONSOLE_CONNECT_ENTRY; + +extern BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole[]; + +#define gEndEntire \ + { \ + END_DEVICE_PATH_TYPE,\ + END_ENTIRE_DEVICE_PATH_SUBTYPE,\ + { \ + END_DEVICE_PATH_LENGTH,\ + 0\ + }\ + } + + +typedef struct { + EMU_VENDOR_DEVICE_PATH_NODE EmuBus; + EMU_VENDOR_DEVICE_PATH_NODE EmuGraphicsWindow; + EFI_DEVICE_PATH_PROTOCOL End; +} EMU_PLATFORM_UGA_DEVICE_PATH; + + +// +// Platform BDS Functions +// + +/** + Perform the memory test base on the memory test intensive level, + and update the memory resource. + + @param Level The memory test intensive level. + + @retval EFI_STATUS Success test all the system memory and update + the memory resource + +**/ +EFI_STATUS +PlatformBootManagerMemoryTest ( + IN EXTENDMEM_COVERAGE_LEVEL Level + ); + + +VOID +PlatformBdsConnectSequence ( + VOID + ); + +#endif // _PLATFORM_BM_H diff --git a/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBmData.c b/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBmData.c new file mode 100644 index 00000000000..6673e83b11a --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBmData.c @@ -0,0 +1,94 @@ +/*++ @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 "PlatformBm.h" + + + +EMU_PLATFORM_UGA_DEVICE_PATH gGopDevicePath = { + { + { + { + 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 + }, + { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (EMU_VENDOR_DEVICE_PATH_NODE)), + (UINT8) ((sizeof (EMU_VENDOR_DEVICE_PATH_NODE)) >> 8) + }, + }, + EMU_GRAPHICS_WINDOW_PROTOCOL_GUID, + }, + 0 + }, + gEndEntire +}; + +EMU_PLATFORM_UGA_DEVICE_PATH gGopDevicePath2 = { + { + { + { + 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 + }, + { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (EMU_VENDOR_DEVICE_PATH_NODE)), + (UINT8) ((sizeof (EMU_VENDOR_DEVICE_PATH_NODE)) >> 8) + }, + }, + EMU_GRAPHICS_WINDOW_PROTOCOL_GUID, + }, + 1 + }, + gEndEntire +}; + +// +// Predefined platform default console device path +// +BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole[] = { + { + (EFI_DEVICE_PATH_PROTOCOL *) &gGopDevicePath, + (CONSOLE_OUT | CONSOLE_IN) + }, + { + (EFI_DEVICE_PATH_PROTOCOL *) &gGopDevicePath2, + (CONSOLE_OUT | CONSOLE_IN) + }, + { + NULL, + 0 + } +}; + diff --git a/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBmLib.inf b/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBmLib.inf new file mode 100644 index 00000000000..3f3244bfcc0 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBmLib.inf @@ -0,0 +1,68 @@ +## @file +# Platfrom Boot Manager library +# +# Do platform action customized by IBV/OEM. +# 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 = PlatformBmLib + FILE_GUID = 59569181-CBF8-2E44-9C3E-C2AB2F5608E1 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = PlatformBootManagerLib|DXE_DRIVER + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + PlatformBm.c + PlatformBm.h + PlatformBmData.c + PlatformBmMemoryTest.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + BaseLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + BaseMemoryLib + DebugLib + PcdLib + UefiBootManagerLib + DevicePathLib + UefiLib + BootLogoLib + HobLib + HiiLib + +[Guids] + gEmuSystemConfigGuid + gEfiEndOfDxeEventGroupGuid + +[Protocols] + gEfiGenericMemTestProtocolGuid + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut + gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand + +[Depex] + gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid diff --git a/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBmMemoryTest.c b/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBmMemoryTest.c new file mode 100644 index 00000000000..7799b28eaec --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/PlatformBmLib/PlatformBmMemoryTest.c @@ -0,0 +1,113 @@ +/** @file + Perform the platform memory test + +Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "PlatformBm.h" + +// +// BDS Platform Functions +// + +/** + Perform the memory test base on the memory test intensive level, + and update the memory resource. + + @param Level The memory test intensive level. + + @retval EFI_STATUS Success test all the system memory and update + the memory resource + +**/ +EFI_STATUS +PlatformBootManagerMemoryTest ( + IN EXTENDMEM_COVERAGE_LEVEL Level + ) +{ + EFI_STATUS Status; + EFI_STATUS KeyStatus; + EFI_STATUS InitStatus; + EFI_STATUS ReturnStatus; + BOOLEAN RequireSoftECCInit; + EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest; + UINT64 TestedMemorySize; + UINT64 TotalMemorySize; + BOOLEAN ErrorOut; + BOOLEAN TestAbort; + EFI_INPUT_KEY Key; + + ReturnStatus = EFI_SUCCESS; + ZeroMem (&Key, sizeof (EFI_INPUT_KEY)); + + TestedMemorySize = 0; + TotalMemorySize = 0; + ErrorOut = FALSE; + TestAbort = FALSE; + + RequireSoftECCInit = FALSE; + + Status = gBS->LocateProtocol ( + &gEfiGenericMemTestProtocolGuid, + NULL, + (VOID **) &GenMemoryTest + ); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + InitStatus = GenMemoryTest->MemoryTestInit ( + GenMemoryTest, + Level, + &RequireSoftECCInit + ); + if (InitStatus == EFI_NO_MEDIA) { + // + // The PEI codes also have the relevant memory test code to check the memory, + // it can select to test some range of the memory or all of them. If PEI code + // checks all the memory, this BDS memory test will has no not-test memory to + // do the test, and then the status of EFI_NO_MEDIA will be returned by + // "MemoryTestInit". So it does not need to test memory again, just return. + // + return EFI_SUCCESS; + } + + DEBUG ((DEBUG_INFO, "Enter memory test.\n")); + do { + Status = GenMemoryTest->PerformMemoryTest ( + GenMemoryTest, + &TestedMemorySize, + &TotalMemorySize, + &ErrorOut, + TestAbort + ); + if (ErrorOut && (Status == EFI_DEVICE_ERROR)) { + PrintXY (10, 10, NULL, NULL, L"Memory Testing failed!"); + ASSERT (0); + } + + + DEBUG ((DEBUG_INFO, "Perform memory test (ESC to skip).\n")); + + if (!PcdGetBool (PcdConInConnectOnDemand)) { + KeyStatus = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + if (!EFI_ERROR (KeyStatus) && (Key.ScanCode == SCAN_ESC)) { + if (!RequireSoftECCInit) { + Status = GenMemoryTest->Finished (GenMemoryTest); + goto Done; + } + + TestAbort = TRUE; + } + } + } while (Status != EFI_NOT_FOUND); + + Status = GenMemoryTest->Finished (GenMemoryTest); + +Done: + DEBUG ((DEBUG_INFO, "%d bytes of system memory tested OK\r\n", TotalMemorySize)); + + return ReturnStatus; +} diff --git a/CdeEmuPkg/EmulatorPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCredentialLib.c b/CdeEmuPkg/EmulatorPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCredentialLib.c new file mode 100644 index 00000000000..8089163d47a --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCredentialLib.c @@ -0,0 +1,237 @@ +/** @file + EmulaotPkg RedfishPlatformCredentialLib instance + + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +BOOLEAN mSecureBootDisabled = FALSE; +BOOLEAN mStopRedfishService = FALSE; + +EFI_STATUS +EFIAPI +LibStopRedfishService ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, + IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType +); + +/** + Return the credential for accessing to Redfish servcice. + + @param[out] AuthMethod The authentication method. + @param[out] UserId User ID. + @param[out] Password USer password. + + @retval EFI_SUCCESS Get the authentication information successfully. + @retval EFI_OUT_OF_RESOURCES There are not enough memory resources. + +**/ +EFI_STATUS +GetRedfishCredential ( + OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod, + OUT CHAR8 **UserId, + OUT CHAR8 **Password +) +{ + UINTN UserIdSize; + UINTN PasswordSize; + + // + // AuthMethod set to HTTP Basic authentication. + // + *AuthMethod = AuthMethodHttpBasic; + + // + // User ID and Password. + // + UserIdSize = AsciiStrSize ((CHAR8 *)PcdGetPtr (PcdRedfishServieUserId)); + PasswordSize = AsciiStrSize ((CHAR8 *)PcdGetPtr (PcdRedfishServiePassword)); + if (UserIdSize == 0 || PasswordSize == 0) { + DEBUG ((DEBUG_ERROR, "Incorrect string of UserID or Password for REdfish service.\n")); + return EFI_INVALID_PARAMETER; + } + *UserId = AllocateZeroPool (UserIdSize); + if (*UserId == NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem (*UserId, (CHAR8 *)PcdGetPtr (PcdRedfishServieUserId), UserIdSize); + + *Password = AllocateZeroPool (PasswordSize); + if (*Password == NULL) { + FreePool (*UserId); + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (*Password, (CHAR8 *)PcdGetPtr (PcdRedfishServiePassword), PasswordSize); + return EFI_SUCCESS; +} + +/** + Retrieve platform's Redfish authentication information. + + This functions returns the Redfish authentication method together with the user Id and + password. + - For AuthMethodNone, the UserId and Password could be used for HTTP header authentication + as defined by RFC7235. + - For AuthMethodRedfishSession, the UserId and Password could be used for Redfish + session login as defined by Redfish API specification (DSP0266). + + Callers are responsible for and freeing the returned string storage. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + @param[out] AuthMethod Type of Redfish authentication method. + @param[out] UserId The pointer to store the returned UserId string. + @param[out] Password The pointer to store the returned Password string. + + @retval EFI_SUCCESS Get the authentication information successfully. + @retval EFI_ACCESS_DENIED SecureBoot is disabled after EndOfDxe. + @retval EFI_INVALID_PARAMETER This or AuthMethod or UserId or Password is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough memory resources. + @retval EFI_UNSUPPORTED Unsupported authentication method is found. + +**/ +EFI_STATUS +EFIAPI +LibCredentialGetAuthInfo ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, + OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod, + OUT CHAR8 **UserId, + OUT CHAR8 **Password +) +{ + EFI_STATUS Status; + + if (This == NULL || AuthMethod == NULL || UserId == NULL || Password == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (mStopRedfishService) { + return EFI_ACCESS_DENIED; + } + + if (mSecureBootDisabled) { + Status = LibStopRedfishService (This, ServiceStopTypeSecureBootDisabled); + if (EFI_ERROR (Status) && Status != EFI_UNSUPPORTED) { + DEBUG ((DEBUG_ERROR, "SecureBoot has been disabled, but failed to stop RedfishService - %r\n", Status)); + return Status; + } + } + + Status = GetRedfishCredential ( + AuthMethod, + UserId, + Password + ); + + return Status; +} + +/** + Notify the Redfish service to stop provide configuration service to this platform. + + This function should be called when the platfrom is about to leave the safe environment. + It will notify the Redfish service provider to abort all logined session, and prohibit + further login with original auth info. GetAuthInfo() will return EFI_UNSUPPORTED once this + function is returned. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + @param[in] ServiceStopType Reason of stopping Redfish service. + + @retval EFI_SUCCESS Service has been stoped successfully. + @retval EFI_INVALID_PARAMETER This is NULL or given the worng ServiceStopType. + @retval EFI_UNSUPPORTED Not support to stop Redfish service. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +LibStopRedfishService ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, + IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType +) +{ + if (ServiceStopType >= ServiceStopTypeMax) { + return EFI_INVALID_PARAMETER; + } + + if (ServiceStopType == ServiceStopTypeSecureBootDisabled) { + // + // Check platform PCD to determine the action for stopping + // Redfish service due to secure boot is disabled. + // + if (!PcdGetBool (PcdRedfishServieStopIfSecureBootDisabled)) { + return EFI_UNSUPPORTED; + } else { + mStopRedfishService = TRUE; + DEBUG ((DEBUG_INFO, "EFI Redfish service is stopped due to SecureBoot is disabled!!\n")); + } + } else if (ServiceStopType == ServiceStopTypeExitBootService) { + // + // Check platform PCD to determine the action for stopping + // Redfish service due to exit boot service. + // + if (PcdGetBool (PcdRedfishServieStopIfExitbootService)) { + return EFI_UNSUPPORTED; + } else { + mStopRedfishService = TRUE; + DEBUG ((DEBUG_INFO, "EFI Redfish service is stopped due to Exit Boot Service!!\n")); + } + } else { + mStopRedfishService = TRUE; + DEBUG ((DEBUG_INFO, "EFI Redfish service is stopped without Redfish service stop type!!\n")); + } + return EFI_SUCCESS; +} +/** + Notification of Exit Boot Service. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL. +**/ +VOID +EFIAPI +LibCredentialExitBootServicesNotify ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This +) +{ + LibStopRedfishService (This, ServiceStopTypeExitBootService); +} + +/** + Notification of End of DXE. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL. +**/ +VOID +EFIAPI +LibCredentialEndOfDxeNotify ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This +) +{ + EFI_STATUS Status; + UINT8 *SecureBootVar; + + // + // Check Secure Boot status and lock Redfish service if Secure Boot is disabled. + // + Status = GetVariable2 (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, (VOID**)&SecureBootVar, NULL); + if (EFI_ERROR (Status) || (*SecureBootVar != SECURE_BOOT_MODE_ENABLE)) { + // + // Secure Boot is disabled + // + mSecureBootDisabled = TRUE; + LibStopRedfishService (This, ServiceStopTypeSecureBootDisabled); + } +} diff --git a/CdeEmuPkg/EmulatorPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCredentialLib.inf b/CdeEmuPkg/EmulatorPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCredentialLib.inf new file mode 100644 index 00000000000..63674f4786b --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/RedfishPlatformCredentialLib/RedfishPlatformCredentialLib.inf @@ -0,0 +1,49 @@ +## @file +# NT32 instance of RedfishPlatformCredentialLib +# +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001000b + BASE_NAME = RedfishPlatformCredentialLib + FILE_GUID = 00CF32A8-495C-3ED8-7C68-E9BB86810EE0 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = RedfishPlatformCredentialLib + +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + RedfishPlatformCredentialLib.c + +[Packages] + EmulatorPkg/EmulatorPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + PcdLib + UefiBootServicesTableLib + UefiLib + +[Pcd] + gEmulatorPkgTokenSpaceGuid.PcdRedfishServieStopIfSecureBootDisabled ## CONSUMES + gEmulatorPkgTokenSpaceGuid.PcdRedfishServieStopIfExitbootService ## CONSUMES + gEmulatorPkgTokenSpaceGuid.PcdRedfishServieUserId ## CONSUMES + gEmulatorPkgTokenSpaceGuid.PcdRedfishServiePassword ## CONSUMES + +[Guids] + gEfiGlobalVariableGuid + +[Depex] + gEfiVariableArchProtocolGuid + diff --git a/CdeEmuPkg/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.c b/CdeEmuPkg/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.c new file mode 100644 index 00000000000..69d66d82c67 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.c @@ -0,0 +1,528 @@ +/** @file + PCI/PCIe network interface instace of RedfishPlatformHostInterfaceLib + + 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 +#include +#include +#include + +#include +#include + +#define VERBOSE_COLUME_SIZE (16) + +REDFISH_OVER_IP_PROTOCOL_DATA *mRedfishOverIpProtocolData; +UINT8 mRedfishProtocolDataSize; + +/** + Get the MAC address of NIC. + + @param[out] MacAddress Pointer to retrieve MAC address + + @retval EFI_SUCCESS MAC address is returned in MacAddress + +**/ +EFI_STATUS +GetMacAddressInformation ( + OUT EFI_MAC_ADDRESS *MacAddress + ) +{ + MAC_ADDR_DEVICE_PATH *Mac; + REST_EX_SERVICE_DEVICE_PATH_DATA *RestExServiceDevicePathData; + EFI_DEVICE_PATH_PROTOCOL *RestExServiceDevicePath; + MAC_ADDR_DEVICE_PATH *MacAddressDevicePath; + + Mac = NULL; + RestExServiceDevicePathData = NULL; + RestExServiceDevicePath = NULL; + + RestExServiceDevicePathData = (REST_EX_SERVICE_DEVICE_PATH_DATA *)PcdGetPtr(PcdRedfishRestExServiceDevicePath); + if (RestExServiceDevicePathData == NULL || + RestExServiceDevicePathData->DevicePathNum == 0 || + !IsDevicePathValid (RestExServiceDevicePathData->DevicePath, 0)) { + return EFI_NOT_FOUND; + } + + RestExServiceDevicePath = RestExServiceDevicePathData->DevicePath; + if (RestExServiceDevicePathData->DevicePathMatchMode != DEVICE_PATH_MATCH_MAC_NODE) { + return EFI_NOT_FOUND; + } + + // + // Find Mac DevicePath Node. + // + while (!IsDevicePathEnd (RestExServiceDevicePath) && + ((DevicePathType (RestExServiceDevicePath) != MESSAGING_DEVICE_PATH) || + (DevicePathSubType (RestExServiceDevicePath) != MSG_MAC_ADDR_DP))) { + RestExServiceDevicePath = NextDevicePathNode (RestExServiceDevicePath); + } + + if (!IsDevicePathEnd (RestExServiceDevicePath)) { + MacAddressDevicePath = (MAC_ADDR_DEVICE_PATH *)RestExServiceDevicePath; + CopyMem ((VOID *)MacAddress, (VOID *)&MacAddressDevicePath->MacAddress, sizeof (EFI_MAC_ADDRESS)); + return EFI_SUCCESS; + } + return EFI_NOT_FOUND; +} + +/** + Get platform Redfish host interface device descriptor. + + @param[out] DeviceType Pointer to retrieve device type. + @param[out] DeviceDescriptor Pointer to retrieve REDFISH_INTERFACE_DATA, caller has to free + this memory using FreePool(). + @retval EFI_SUCCESS Device descriptor is returned successfully in DeviceDescriptor. + @retval EFI_NOT_FOUND No Redfish host interface descriptor provided on this platform. + @retval Others Fail to get device descriptor. +**/ +EFI_STATUS +RedfishPlatformHostInterfaceDeviceDescriptor ( + OUT UINT8 *DeviceType, + OUT REDFISH_INTERFACE_DATA **DeviceDescriptor +) +{ + EFI_STATUS Status; + EFI_MAC_ADDRESS MacAddress; + REDFISH_INTERFACE_DATA *RedfishInterfaceData; + PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2 *ThisDeviceDescriptor; + + RedfishInterfaceData = AllocateZeroPool (sizeof (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2) + 1); + if (RedfishInterfaceData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + RedfishInterfaceData->DeviceType = REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2; + // + // Fill up device type information. + // + ThisDeviceDescriptor = (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2 *)((UINT8 *)RedfishInterfaceData + 1); + ThisDeviceDescriptor->Length = sizeof (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2) + 1; + Status = GetMacAddressInformation (&MacAddress); + if (EFI_ERROR (Status)) { + FreePool (RedfishInterfaceData); + return EFI_NOT_FOUND; + } + CopyMem ((VOID *)&ThisDeviceDescriptor->MacAddress, (VOID *)&MacAddress, sizeof (ThisDeviceDescriptor->MacAddress)); + *DeviceType = REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2; + *DeviceDescriptor = RedfishInterfaceData; + return EFI_SUCCESS; +} +/** + Get platform Redfish host interface protocol data. + Caller should pass NULL in ProtocolRecord to retrive the first protocol record. + Then continuously pass previous ProtocolRecord for retrieving the next ProtocolRecord. + + @param[out] ProtocolRecord Pointer to retrieve the protocol record. + caller has to free the new protocol record returned from + this function using FreePool(). + @param[in] IndexOfProtocolData The index of protocol data. + + @retval EFI_SUCCESS Protocol records are all returned. + @retval EFI_NOT_FOUND No more protocol records. + @retval Others Fail to get protocol records. +**/ +EFI_STATUS +RedfishPlatformHostInterfaceProtocolData ( + OUT MC_HOST_INTERFACE_PROTOCOL_RECORD **ProtocolRecord, + IN UINT8 IndexOfProtocolData +) +{ + MC_HOST_INTERFACE_PROTOCOL_RECORD *ThisProtocolRecord; + + if (mRedfishOverIpProtocolData == 0) { + return EFI_NOT_FOUND; + } + if (IndexOfProtocolData == 0) { + // + // Return the first Redfish protocol data to caller. We only have + // one protocol data in this case. + // + ThisProtocolRecord = (MC_HOST_INTERFACE_PROTOCOL_RECORD *) AllocatePool (mRedfishProtocolDataSize + sizeof (MC_HOST_INTERFACE_PROTOCOL_RECORD) - 1); + ThisProtocolRecord->ProtocolType = MCHostInterfaceProtocolTypeRedfishOverIP; + ThisProtocolRecord->ProtocolTypeDataLen = mRedfishProtocolDataSize; + CopyMem ((VOID *)&ThisProtocolRecord->ProtocolTypeData, (VOID *)mRedfishOverIpProtocolData, mRedfishProtocolDataSize); + *ProtocolRecord = ThisProtocolRecord; + return EFI_SUCCESS; + } + return EFI_NOT_FOUND; +} +/** + Dump IPv4 address. + + @param[in] Ip IPv4 address +**/ +VOID +InternalDumpIp4Addr ( + IN EFI_IPv4_ADDRESS *Ip + ) +{ + UINTN Index; + + for (Index = 0; Index < 4; Index++) { + DEBUG ((DEBUG_VERBOSE, "%d", Ip->Addr[Index])); + if (Index < 3) { + DEBUG ((DEBUG_VERBOSE, ".")); + } + } + + DEBUG ((DEBUG_VERBOSE, "\n")); +} +/** + Dump IPv6 address. + + @param[in] Ip IPv6 address +**/ +VOID +InternalDumpIp6Addr ( + IN EFI_IPv6_ADDRESS *Ip + ) +{ + UINTN Index; + + for (Index = 0; Index < 16; Index++) { + if (Ip->Addr[Index] != 0) { + DEBUG ((DEBUG_VERBOSE, "%x", Ip->Addr[Index])); + } + Index++; + + if (Index > 15) { + return; + } + + if (((Ip->Addr[Index] & 0xf0) == 0) && (Ip->Addr[Index - 1] != 0)) { + DEBUG ((DEBUG_VERBOSE, "0")); + } + DEBUG ((DEBUG_VERBOSE, "%x", Ip->Addr[Index])); + + if (Index < 15) { + DEBUG ((DEBUG_VERBOSE, ":")); + } + } + DEBUG ((DEBUG_VERBOSE, "\n")); +} +/** + Dump data + + @param[in] Data Pointer to data. + @param[in] Size size of data to dump. +**/ +VOID +InternalDumpData ( + IN UINT8 *Data, + IN UINTN Size + ) +{ + UINTN Index; + for (Index = 0; Index < Size; Index++) { + DEBUG ((DEBUG_VERBOSE, "%02x ", (UINTN)Data[Index])); + } +} +/** + Dump hex data + + @param[in] Data Pointer to hex data. + @param[in] Size size of hex data to dump. +**/ +VOID +InternalDumpHex ( + IN UINT8 *Data, + IN UINTN Size + ) +{ + UINTN Index; + UINTN Count; + UINTN Left; + + Count = Size / VERBOSE_COLUME_SIZE; + Left = Size % VERBOSE_COLUME_SIZE; + for (Index = 0; Index < Count; Index++) { + InternalDumpData (Data + Index * VERBOSE_COLUME_SIZE, VERBOSE_COLUME_SIZE); + DEBUG ((DEBUG_VERBOSE, "\n")); + } + + if (Left != 0) { + InternalDumpData (Data + Index * VERBOSE_COLUME_SIZE, Left); + DEBUG ((DEBUG_VERBOSE, "\n")); + } + + DEBUG ((DEBUG_VERBOSE, "\n")); +} +/** + Dump Redfish over IP protocol data + + @param[in] RedfishProtocolData Pointer to REDFISH_OVER_IP_PROTOCOL_DATA + @param[in] RedfishProtocolDataSize size of data to dump. +**/ +VOID +DumpRedfishIpProtocolData ( + IN REDFISH_OVER_IP_PROTOCOL_DATA *RedfishProtocolData, + IN UINT8 RedfishProtocolDataSize + ) +{ + CHAR16 Hostname[16]; + + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData: \n")); + InternalDumpHex ((UINT8 *) RedfishProtocolData, RedfishProtocolDataSize); + + DEBUG ((DEBUG_VERBOSE, "Parsing as below: \n")); + + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->ServiceUuid - %g\n", &(RedfishProtocolData->ServiceUuid))); + + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpAssignmentType - %d\n", RedfishProtocolData->HostIpAssignmentType)); + + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpAddressFormat - %d\n", RedfishProtocolData->HostIpAddressFormat)); + + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpAddress: \n")); + if (RedfishProtocolData->HostIpAddressFormat == 0x01) { + InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->HostIpAddress)); + } else { + InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->HostIpAddress)); + } + + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpMask: \n")); + if (RedfishProtocolData->HostIpAddressFormat == 0x01) { + InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->HostIpMask)); + } else { + InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->HostIpMask)); + } + + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpDiscoveryType - %d\n", RedfishProtocolData->RedfishServiceIpDiscoveryType)); + + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpAddressFormat - %d\n", RedfishProtocolData->RedfishServiceIpAddressFormat)); + + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpAddress: \n")); + if (RedfishProtocolData->RedfishServiceIpAddressFormat == 0x01) { + InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->RedfishServiceIpAddress)); + } else { + InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->RedfishServiceIpAddress)); + } + + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpMask: \n")); + if (RedfishProtocolData->RedfishServiceIpAddressFormat == 0x01) { + InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->RedfishServiceIpMask)); + } else { + InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->RedfishServiceIpMask)); + } + + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpPort - %d\n", RedfishProtocolData->RedfishServiceIpPort)); + + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceVlanId - %d\n", RedfishProtocolData->RedfishServiceVlanId)); + + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceHostnameLength - %d\n", RedfishProtocolData->RedfishServiceHostnameLength)); + + AsciiStrToUnicodeStrS((CHAR8 *) RedfishProtocolData->RedfishServiceHostname, Hostname, sizeof (Hostname) / sizeof (Hostname[0])); + DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceHostname - %s\n", Hostname)); +} + +/** + Get Redfish host interface protocol data from variale. + + @param[out] RedfishProtocolData Pointer to retrieve REDFISH_OVER_IP_PROTOCOL_DATA. + @param[out] RedfishProtocolDataSize Size of REDFISH_OVER_IP_PROTOCOL_DATA. + + @retval EFI_SUCESS REDFISH_OVER_IP_PROTOCOL_DATA is returned successfully. +**/ +EFI_STATUS +GetRedfishRecordFromVariable ( + OUT REDFISH_OVER_IP_PROTOCOL_DATA **RedfishProtocolData, + OUT UINT8 *RedfishProtocolDataSize + ) +{ + EFI_STATUS Status; + UINT8 HostIpAssignmentType; + UINTN HostIpAssignmentTypeSize; + EFI_IPv4_ADDRESS HostIpAddress; + UINTN IPv4DataSize; + EFI_IPv4_ADDRESS HostIpMask; + EFI_IPv4_ADDRESS RedfishServiceIpAddress; + EFI_IPv4_ADDRESS RedfishServiceIpMask; + UINT16 RedfishServiceIpPort; + UINTN IpPortDataSize; + UINT8 HostNameSize; + CHAR8 RedfishHostName[20]; + + if (RedfishProtocolData == NULL || RedfishProtocolDataSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // 1. Retrieve Address Information from variable. + // + Status = gRT->GetVariable ( + L"HostIpAssignmentType", + &gEmuRedfishServiceGuid, + NULL, + &HostIpAssignmentTypeSize, + &HostIpAssignmentType + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable HostIpAssignmentType - %r\n", Status)); + return Status; + } + + IPv4DataSize = sizeof (EFI_IPv4_ADDRESS); + if (HostIpAssignmentType == 1 ) { + Status = gRT->GetVariable ( + L"HostIpAddress", + &gEmuRedfishServiceGuid, + NULL, + &IPv4DataSize, + &HostIpAddress + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable HostIpAddress - %r\n", Status)); + return Status; + } + + Status = gRT->GetVariable ( + L"HostIpMask", + &gEmuRedfishServiceGuid, + NULL, + &IPv4DataSize, + &HostIpMask + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable HostIpMask - %r\n", Status)); + return Status; + } + } + + Status = gRT->GetVariable ( + L"RedfishServiceIpAddress", + &gEmuRedfishServiceGuid, + NULL, + &IPv4DataSize, + &RedfishServiceIpAddress + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable RedfishServiceIpAddress - %r\n", Status)); + return Status; + } + + Status = gRT->GetVariable ( + L"RedfishServiceIpMask", + &gEmuRedfishServiceGuid, + NULL, + &IPv4DataSize, + &RedfishServiceIpMask + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable RedfishServiceIpMask - %r\n", Status)); + return Status; + } + + Status = gRT->GetVariable ( + L"RedfishServiceIpPort", + &gEmuRedfishServiceGuid, + NULL, + &IpPortDataSize, + &RedfishServiceIpPort + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable RedfishServiceIpPort - %r\n", Status)); + return Status; + } + + AsciiSPrint ( + RedfishHostName, + sizeof (RedfishHostName), + "%d.%d.%d.%d", + RedfishServiceIpAddress.Addr[0], + RedfishServiceIpAddress.Addr[1], + RedfishServiceIpAddress.Addr[2], + RedfishServiceIpAddress.Addr[3] + ); + + HostNameSize = (UINT8) AsciiStrLen (RedfishHostName) + 1; + + // + // 2. Protocol Data Size. + // + *RedfishProtocolDataSize = sizeof (REDFISH_OVER_IP_PROTOCOL_DATA) - 1 + HostNameSize; + + // + // 3. Protocol Data. + // + *RedfishProtocolData = (REDFISH_OVER_IP_PROTOCOL_DATA *) AllocateZeroPool (*RedfishProtocolDataSize); + if (*RedfishProtocolData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + CopyGuid (&(*RedfishProtocolData)->ServiceUuid, &gEmuRedfishServiceGuid); + + (*RedfishProtocolData)->HostIpAssignmentType = HostIpAssignmentType; + (*RedfishProtocolData)->HostIpAddressFormat = 1; // Only support IPv4 + + if (HostIpAssignmentType == 1 ) { + (*RedfishProtocolData)->HostIpAddress[0] = HostIpAddress.Addr[0]; + (*RedfishProtocolData)->HostIpAddress[1] = HostIpAddress.Addr[1]; + (*RedfishProtocolData)->HostIpAddress[2] = HostIpAddress.Addr[2]; + (*RedfishProtocolData)->HostIpAddress[3] = HostIpAddress.Addr[3]; + + (*RedfishProtocolData)->HostIpMask[0] = HostIpMask.Addr[0]; + (*RedfishProtocolData)->HostIpMask[1] = HostIpMask.Addr[1]; + (*RedfishProtocolData)->HostIpMask[2] = HostIpMask.Addr[2]; + (*RedfishProtocolData)->HostIpMask[3] = HostIpMask.Addr[3]; + } + + (*RedfishProtocolData)->RedfishServiceIpDiscoveryType = 1; // Use static IP address + (*RedfishProtocolData)->RedfishServiceIpAddressFormat = 1; // Only support IPv4 + + (*RedfishProtocolData)->RedfishServiceIpAddress[0] = RedfishServiceIpAddress.Addr[0]; + (*RedfishProtocolData)->RedfishServiceIpAddress[1] = RedfishServiceIpAddress.Addr[1]; + (*RedfishProtocolData)->RedfishServiceIpAddress[2] = RedfishServiceIpAddress.Addr[2]; + (*RedfishProtocolData)->RedfishServiceIpAddress[3] = RedfishServiceIpAddress.Addr[3]; + + (*RedfishProtocolData)->RedfishServiceIpMask[0] = RedfishServiceIpMask.Addr[0]; + (*RedfishProtocolData)->RedfishServiceIpMask[1] = RedfishServiceIpMask.Addr[1]; + (*RedfishProtocolData)->RedfishServiceIpMask[2] = RedfishServiceIpMask.Addr[2]; + (*RedfishProtocolData)->RedfishServiceIpMask[3] = RedfishServiceIpMask.Addr[3]; + + (*RedfishProtocolData)->RedfishServiceIpPort = RedfishServiceIpPort; + (*RedfishProtocolData)->RedfishServiceVlanId = 0xffffffff; + + (*RedfishProtocolData)->RedfishServiceHostnameLength = HostNameSize; + AsciiStrCpyS ((CHAR8 *) ((*RedfishProtocolData)->RedfishServiceHostname), HostNameSize, RedfishHostName); + + return Status; +} + +/** + Construct Redfish host interface protocol data. + + @param ImageHandle The image handle. + @param SystemTable The system table. + + @retval EFI_SUCEESS Install Boot manager menu success. + @retval Other Return error status. + +**/ +EFI_STATUS +EFIAPI +RedfishPlatformHostInterfaceConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_STATUS Status; + + Status = GetRedfishRecordFromVariable (&mRedfishOverIpProtocolData, &mRedfishProtocolDataSize); + DEBUG ((DEBUG_INFO, "%a: GetRedfishRecordFromVariable() - %r\n", __FUNCTION__, Status)); + if (!EFI_ERROR (Status)) { + DumpRedfishIpProtocolData (mRedfishOverIpProtocolData, mRedfishProtocolDataSize); + } + return EFI_SUCCESS; +} diff --git a/CdeEmuPkg/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.inf b/CdeEmuPkg/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.inf new file mode 100644 index 00000000000..8f1f0cfddee --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.inf @@ -0,0 +1,47 @@ +## @file +# NULL instance of RedfishPlatformHostInterfaceLib +# +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001000b + BASE_NAME = RedfishPlatformHostInterfaceLib + FILE_GUID = D5ECB7F2-4906-94E2-45B1-31BF4FD90122 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = RedfishPlatformHostInterfaceLib + CONSTRUCTOR = RedfishPlatformHostInterfaceConstructor +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + RedfishPlatformHostInterfaceLib.c + +[Packages] + EmulatorPkg/EmulatorPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + PcdLib + UefiLib + +[Pcd] + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceDevicePath ## CONSUMES + +[Guids] + gEmuRedfishServiceGuid + +[Depex] + gEfiVariableArchProtocolGuid AND + gEfiVariableWriteArchProtocolGuid diff --git a/CdeEmuPkg/EmulatorPkg/Library/SecPeiServicesLib/FwVol.c b/CdeEmuPkg/EmulatorPkg/Library/SecPeiServicesLib/FwVol.c new file mode 100644 index 00000000000..6263891c3f2 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/SecPeiServicesLib/FwVol.c @@ -0,0 +1,275 @@ +/*++ @file + A simple FV stack so the SEC can extract the SEC Core from an + FV. + +Copyright (c) 2006, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + + +#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \ + (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1)) + +EFI_FFS_FILE_STATE +GetFileState ( + IN UINT8 ErasePolarity, + IN EFI_FFS_FILE_HEADER *FfsHeader + ) +/*++ + +Routine Description: + Returns the highest bit set of the State field + +Arguments: + ErasePolarity - Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY + in the Attributes field. + FfsHeader - Pointer to FFS File Header. + +Returns: + Returns the highest bit in the State field + +**/ +{ + EFI_FFS_FILE_STATE FileState; + EFI_FFS_FILE_STATE HighestBit; + + FileState = FfsHeader->State; + + if (ErasePolarity != 0) { + FileState = (EFI_FFS_FILE_STATE)~FileState; + } + + HighestBit = 0x80; + while (HighestBit != 0 && (HighestBit & FileState) == 0) { + HighestBit >>= 1; + } + + return HighestBit; +} + +UINT8 +CalculateHeaderChecksum ( + IN EFI_FFS_FILE_HEADER *FileHeader + ) +/*++ + +Routine Description: + Calculates the checksum of the header of a file. + +Arguments: + FileHeader - Pointer to FFS File Header. + +Returns: + Checksum of the header. + +**/ +{ + UINT8 *ptr; + UINTN Index; + UINT8 Sum; + + Sum = 0; + ptr = (UINT8 *) FileHeader; + + for (Index = 0; Index < sizeof (EFI_FFS_FILE_HEADER) - 3; Index += 4) { + Sum = (UINT8) (Sum + ptr[Index]); + Sum = (UINT8) (Sum + ptr[Index + 1]); + Sum = (UINT8) (Sum + ptr[Index + 2]); + Sum = (UINT8) (Sum + ptr[Index + 3]); + } + + for (; Index < sizeof (EFI_FFS_FILE_HEADER); Index++) { + Sum = (UINT8) (Sum + ptr[Index]); + } + // + // State field (since this indicates the different state of file). + // + Sum = (UINT8) (Sum - FileHeader->State); + // + // Checksum field of the file is not part of the header checksum. + // + Sum = (UINT8) (Sum - FileHeader->IntegrityCheck.Checksum.File); + + return Sum; +} + +EFI_STATUS +SecFfsFindNextFile ( + IN EFI_FV_FILETYPE SearchType, + IN EFI_PEI_FV_HANDLE FvHandle, + IN OUT EFI_PEI_FILE_HANDLE *FileHandle + ) +/*++ + +Routine Description: + Given the input file pointer, search for the next matching file in the + FFS volume as defined by SearchType. The search starts from FileHeader inside + the Firmware Volume defined by FwVolHeader. + +Arguments: + SearchType - Filter to find only files of this type. + Type EFI_FV_FILETYPE_ALL causes no filtering to be done. + FwVolHeader - Pointer to the FV header of the volume to search. + This parameter must point to a valid FFS volume. + FileHeader - Pointer to the current file from which to begin searching. + This pointer will be updated upon return to reflect the file + found. + +Returns: + EFI_NOT_FOUND - No files matching the search criteria were found + EFI_SUCCESS + +**/ +{ + EFI_FFS_FILE_HEADER *FfsFileHeader; + UINT32 FileLength; + UINT32 FileOccupiedSize; + UINT32 FileOffset; + UINT64 FvLength; + UINT8 ErasePolarity; + UINT8 FileState; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + EFI_FFS_FILE_HEADER **FileHeader; + + // + // Convert the handle of FV to FV header for memory-mapped firmware volume + // + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) FvHandle; + FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle; + + FvLength = FwVolHeader->FvLength; + if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) { + ErasePolarity = 1; + } else { + ErasePolarity = 0; + } + // + // If FileHeader is not specified (NULL) start with the first file in the + // firmware volume. Otherwise, start from the FileHeader. + // + if (*FileHeader == NULL) { + FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FwVolHeader + FwVolHeader->HeaderLength); + } else { + // + // Length is 24 bits wide so mask upper 8 bits + // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned. + // + FileLength = *(UINT32 *) (*FileHeader)->Size & 0x00FFFFFF; + FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8); + FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) *FileHeader + FileOccupiedSize); + } + + FileOffset = (UINT32) ((UINT8 *) FfsFileHeader - (UINT8 *) FwVolHeader); + + while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) { + // + // Get FileState which is the highest bit of the State + // + FileState = GetFileState (ErasePolarity, FfsFileHeader); + + switch (FileState) { + + case EFI_FILE_HEADER_INVALID: + FileOffset += sizeof (EFI_FFS_FILE_HEADER); + FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER)); + break; + + case EFI_FILE_DATA_VALID: + case EFI_FILE_MARKED_FOR_UPDATE: + if (CalculateHeaderChecksum (FfsFileHeader) == 0) { + FileLength = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF; + FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8); + + if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) { + + *FileHeader = FfsFileHeader; + + return EFI_SUCCESS; + } + + FileOffset += FileOccupiedSize; + FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize); + } else { + return EFI_NOT_FOUND; + } + break; + + case EFI_FILE_DELETED: + FileLength = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF; + FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8); + FileOffset += FileOccupiedSize; + FfsFileHeader = (EFI_FFS_FILE_HEADER *) ((UINT8 *) FfsFileHeader + FileOccupiedSize); + break; + + default: + return EFI_NOT_FOUND; + + } + } + + return EFI_NOT_FOUND; +} + +EFI_STATUS +SecFfsFindSectionData ( + IN EFI_SECTION_TYPE SectionType, + IN EFI_FFS_FILE_HEADER *FfsFileHeader, + IN OUT VOID **SectionData + ) +/*++ + +Routine Description: + Given the input file pointer, search for the next matching section in the + FFS volume. + +Arguments: + SearchType - Filter to find only sections of this type. + FfsFileHeader - Pointer to the current file to search. + SectionData - Pointer to the Section matching SectionType in FfsFileHeader. + NULL if section not found + +Returns: + EFI_NOT_FOUND - No files matching the search criteria were found + EFI_SUCCESS + +**/ +{ + UINT32 FileSize; + EFI_COMMON_SECTION_HEADER *Section; + UINT32 SectionLength; + UINT32 ParsedLength; + + // + // Size is 24 bits wide so mask upper 8 bits. + // Does not include FfsFileHeader header size + // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned. + // + Section = (EFI_COMMON_SECTION_HEADER *) (FfsFileHeader + 1); + FileSize = *(UINT32 *) (FfsFileHeader->Size) & 0x00FFFFFF; + FileSize -= sizeof (EFI_FFS_FILE_HEADER); + + *SectionData = NULL; + ParsedLength = 0; + while (ParsedLength < FileSize) { + if (Section->Type == SectionType) { + *SectionData = (VOID *) (Section + 1); + return EFI_SUCCESS; + } + // + // Size is 24 bits wide so mask upper 8 bits. + // SectionLength is adjusted it is 4 byte aligned. + // Go to the next section + // + SectionLength = *(UINT32 *) Section->Size & 0x00FFFFFF; + SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4); + + ParsedLength += SectionLength; + Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + SectionLength); + } + + return EFI_NOT_FOUND; +} + diff --git a/CdeEmuPkg/EmulatorPkg/Library/SecPeiServicesLib/PeiServicesLib.c b/CdeEmuPkg/EmulatorPkg/Library/SecPeiServicesLib/PeiServicesLib.c new file mode 100644 index 00000000000..2ddbfbc94e3 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/SecPeiServicesLib/PeiServicesLib.c @@ -0,0 +1,561 @@ +/** @file + Implementation for PEI Services Library. + + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + + +#include +#include +#include +#include +#include + + + +EFI_STATUS +SecFfsFindNextFile ( + IN EFI_FV_FILETYPE SearchType, + IN EFI_PEI_FV_HANDLE VolumeHandle, + IN OUT EFI_PEI_FILE_HANDLE *FileHandle + ); + +EFI_STATUS +SecFfsFindSectionData ( + IN EFI_SECTION_TYPE SectionType, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData + ); + + +/** + This service enables a given PEIM to register an interface into the PEI Foundation. + + @param PpiList A pointer to the list of interfaces that the caller shall install. + + @retval EFI_SUCCESS The interface was successfully installed. + @retval EFI_INVALID_PARAMETER The PpiList pointer is NULL. + @retval EFI_INVALID_PARAMETER Any of the PEI PPI descriptors in the list do not have the + EFI_PEI_PPI_DESCRIPTOR_PPI bit set in the Flags field. + @retval EFI_OUT_OF_RESOURCES There is no additional space in the PPI database. + +**/ +EFI_STATUS +EFIAPI +PeiServicesInstallPpi ( + IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + This service enables PEIMs to replace an entry in the PPI database with an alternate entry. + + @param OldPpi The pointer to the old PEI PPI Descriptors. + @param NewPpi The pointer to the new PEI PPI Descriptors. + + @retval EFI_SUCCESS The interface was successfully installed. + @retval EFI_INVALID_PARAMETER The OldPpi or NewPpi is NULL. + @retval EFI_INVALID_PARAMETER Any of the PEI PPI descriptors in the list do not have the + EFI_PEI_PPI_DESCRIPTOR_PPI bit set in the Flags field. + @retval EFI_OUT_OF_RESOURCES There is no additional space in the PPI database. + @retval EFI_NOT_FOUND The PPI for which the reinstallation was requested has not been + installed. + +**/ +EFI_STATUS +EFIAPI +PeiServicesReInstallPpi ( + IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi, + IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + This service enables PEIMs to discover a given instance of an interface. + + So this is, well a hack, so we can reuse the same libraries as the PEI Core + for XIP modules.... + + @param Guid A pointer to the GUID whose corresponding interface needs to be + found. + @param Instance The N-th instance of the interface that is required. + @param PpiDescriptor A pointer to instance of the EFI_PEI_PPI_DESCRIPTOR. + @param Ppi A pointer to the instance of the interface. + + @retval EFI_SUCCESS The interface was successfully returned. + @retval EFI_NOT_FOUND The PPI descriptor is not found in the database. + +**/ +EFI_STATUS +EFIAPI +PeiServicesLocatePpi ( + IN CONST EFI_GUID *Guid, + IN UINTN Instance, + IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, + IN OUT VOID **Ppi + ) +{ + EFI_PEI_PPI_DESCRIPTOR *PpiList; + + if (Instance != 0) { + return EFI_NOT_FOUND; + } + + for (PpiList = EMU_MAGIC_PAGE()->PpiList; ; PpiList++) { + if (CompareGuid (PpiList->Guid, Guid)) { + if (PpiDescriptor != NULL) { + *PpiDescriptor = PpiList; + } + if (Ppi != NULL) { + *Ppi = PpiList->Ppi; + } + return EFI_SUCCESS; + } + + if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) { + break; + } + } + + + return EFI_NOT_FOUND; +} + +/** + This service enables PEIMs to register a given service to be invoked when another service is + installed or reinstalled. + + @param NotifyList A pointer to the list of notification interfaces + that the caller shall install. + + @retval EFI_SUCCESS The interface was successfully installed. + @retval EFI_INVALID_PARAMETER The NotifyList pointer is NULL. + @retval EFI_INVALID_PARAMETER Any of the PEI notify descriptors in the list do + not have the EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES + bit set in the Flags field. + @retval EFI_OUT_OF_RESOURCES There is no additional space in the PPI database. + +**/ +EFI_STATUS +EFIAPI +PeiServicesNotifyPpi ( + IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + This service enables PEIMs to ascertain the present value of the boot mode. + + @param BootMode A pointer to contain the value of the boot mode. + + @retval EFI_SUCCESS The boot mode was returned successfully. + @retval EFI_INVALID_PARAMETER BootMode is NULL. + +**/ +EFI_STATUS +EFIAPI +PeiServicesGetBootMode ( + OUT EFI_BOOT_MODE *BootMode + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + This service enables PEIMs to update the boot mode variable. + + @param BootMode The value of the boot mode to set. + + @retval EFI_SUCCESS The value was successfully updated + +**/ +EFI_STATUS +EFIAPI +PeiServicesSetBootMode ( + IN EFI_BOOT_MODE BootMode + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + This service enables a PEIM to ascertain the address of the list of HOBs in memory. + + @param HobList A pointer to the list of HOBs that the PEI Foundation + will initialize. + + @retval EFI_SUCCESS The list was successfully returned. + @retval EFI_NOT_AVAILABLE_YET The HOB list is not yet published. + +**/ +EFI_STATUS +EFIAPI +PeiServicesGetHobList ( + OUT VOID **HobList + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + This service enables PEIMs to create various types of HOBs. + + @param Type The type of HOB to be installed. + @param Length The length of the HOB to be added. + @param Hob The address of a pointer that will contain the + HOB header. + + @retval EFI_SUCCESS The HOB was successfully created. + @retval EFI_OUT_OF_RESOURCES There is no additional space for HOB creation. + +**/ +EFI_STATUS +EFIAPI +PeiServicesCreateHob ( + IN UINT16 Type, + IN UINT16 Length, + OUT VOID **Hob + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + This service enables PEIMs to discover additional firmware volumes. + + @param Instance This instance of the firmware volume to find. The + value 0 is the Boot Firmware Volume (BFV). + @param VolumeHandle Handle of the firmware volume header of the volume + to return. + + @retval EFI_SUCCESS The volume was found. + @retval EFI_NOT_FOUND The volume was not found. + @retval EFI_INVALID_PARAMETER FwVolHeader is NULL. + +**/ +EFI_STATUS +EFIAPI +PeiServicesFfsFindNextVolume ( + IN UINTN Instance, + IN OUT EFI_PEI_FV_HANDLE *VolumeHandle + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + This service enables PEIMs to discover additional firmware files. + + @param SearchType A filter to find files only of this type. + @param VolumeHandle The pointer to the firmware volume header of the + volume to search. This parameter must point to a + valid FFS volume. + @param FileHandle Handle of the current file from which to begin searching. + + @retval EFI_SUCCESS The file was found. + @retval EFI_NOT_FOUND The file was not found. + @retval EFI_NOT_FOUND The header checksum was not zero. + +**/ +EFI_STATUS +EFIAPI +PeiServicesFfsFindNextFile ( + IN EFI_FV_FILETYPE SearchType, + IN EFI_PEI_FV_HANDLE VolumeHandle, + IN OUT EFI_PEI_FILE_HANDLE *FileHandle + ) +{ + return SecFfsFindNextFile (SearchType, VolumeHandle, FileHandle); +} + +/** + This service enables PEIMs to discover sections of a given type within a valid FFS file. + + @param SectionType The value of the section type to find. + @param FileHandle A pointer to the file header that contains the set + of sections to be searched. + @param SectionData A pointer to the discovered section, if successful. + + @retval EFI_SUCCESS The section was found. + @retval EFI_NOT_FOUND The section was not found. + +**/ +EFI_STATUS +EFIAPI +PeiServicesFfsFindSectionData ( + IN EFI_SECTION_TYPE SectionType, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData + ) +{ + return SecFfsFindSectionData (SectionType, FileHandle, SectionData); +} + +/** + This service enables PEIMs to register the permanent memory configuration + that has been initialized with the PEI Foundation. + + @param MemoryBegin The value of a region of installed memory. + @param MemoryLength The corresponding length of a region of installed memory. + + @retval EFI_SUCCESS The region was successfully installed in a HOB. + @retval EFI_INVALID_PARAMETER MemoryBegin and MemoryLength are illegal for this system. + @retval EFI_OUT_OF_RESOURCES There is no additional space for HOB creation. + +**/ +EFI_STATUS +EFIAPI +PeiServicesInstallPeiMemory ( + IN EFI_PHYSICAL_ADDRESS MemoryBegin, + IN UINT64 MemoryLength + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + This service enables PEIMs to allocate memory after the permanent memory has been + installed by a PEIM. + + @param MemoryType Type of memory to allocate. + @param Pages The number of pages to allocate. + @param Memory Pointer of memory allocated. + + @retval EFI_SUCCESS The memory range was successfully allocated. + @retval EFI_INVALID_PARAMETER Type is not equal to AllocateAnyPages. + @retval EFI_NOT_AVAILABLE_YET Called with permanent memory not available. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + +**/ +EFI_STATUS +EFIAPI +PeiServicesAllocatePages ( + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT EFI_PHYSICAL_ADDRESS *Memory + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + This service allocates memory from the Hand-Off Block (HOB) heap. + + @param Size The number of bytes to allocate from the pool. + @param Buffer If the call succeeds, a pointer to a pointer to + the allocate buffer; otherwise, undefined. + + @retval EFI_SUCCESS The allocation was successful + @retval EFI_OUT_OF_RESOURCES There is not enough heap to allocate the requested size. + +**/ +EFI_STATUS +EFIAPI +PeiServicesAllocatePool ( + IN UINTN Size, + OUT VOID **Buffer + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + Resets the entire platform. + + @retval EFI_SUCCESS The function completed successfully. + @retval EFI_NOT_AVAILABLE_YET The service has not been installed yet. + +**/ +EFI_STATUS +EFIAPI +PeiServicesResetSystem ( + VOID + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + This service is a wrapper for the PEI Service RegisterForShadow(), except the + pointer to the PEI Services Table has been removed. See the Platform + Initialization Pre-EFI Initialization Core Interface Specification for details. + + @param FileHandle PEIM's file handle. Must be the currently + executing PEIM. + + @retval EFI_SUCCESS The PEIM was successfully registered for + shadowing. + + @retval EFI_ALREADY_STARTED The PEIM was previously + registered for shadowing. + + @retval EFI_NOT_FOUND The FileHandle does not refer to a + valid file handle. +**/ +EFI_STATUS +EFIAPI +PeiServicesRegisterForShadow ( + IN EFI_PEI_FILE_HANDLE FileHandle + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + This service is a wrapper for the PEI Service FfsGetFileInfo(), except the pointer to the PEI Services + Table has been removed. See the Platform Initialization Pre-EFI Initialization Core Interface + Specification for details. + + @param FileHandle The handle of the file. + + @param FileInfo Upon exit, points to the file's + information. + + @retval EFI_SUCCESS File information returned. + + @retval EFI_INVALID_PARAMETER If FileHandle does not + represent a valid file. + + @retval EFI_INVALID_PARAMETER FileInfo is NULL. + +**/ +EFI_STATUS +EFIAPI +PeiServicesFfsGetFileInfo ( + IN CONST EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_FV_FILE_INFO *FileInfo + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + + +/** + This service is a wrapper for the PEI Service FfsFindByName(), except the pointer to the PEI Services + Table has been removed. See the Platform Initialization Pre-EFI Initialization Core Interface + Specification for details. + + @param FileName A pointer to the name of the file to + find within the firmware volume. + + @param VolumeHandle The firmware volume to search FileHandle + Upon exit, points to the found file's + handle or NULL if it could not be found. + @param FileHandle The pointer to found file handle + + @retval EFI_SUCCESS File was found. + + @retval EFI_NOT_FOUND File was not found. + + @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or + FileName was NULL. + +**/ +EFI_STATUS +EFIAPI +PeiServicesFfsFindFileByName ( + IN CONST EFI_GUID *FileName, + IN CONST EFI_PEI_FV_HANDLE VolumeHandle, + OUT EFI_PEI_FILE_HANDLE *FileHandle + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + + +/** + This service is a wrapper for the PEI Service FfsGetVolumeInfo(), except the pointer to the PEI Services + Table has been removed. See the Platform Initialization Pre-EFI Initialization Core Interface + Specification for details. + + @param VolumeHandle Handle of the volume. + + @param VolumeInfo Upon exit, points to the volume's + information. + + @retval EFI_SUCCESS File information returned. + + @retval EFI_INVALID_PARAMETER If FileHandle does not + represent a valid file. + + @retval EFI_INVALID_PARAMETER If FileInfo is NULL. + +**/ +EFI_STATUS +EFIAPI +PeiServicesFfsGetVolumeInfo ( + IN EFI_PEI_FV_HANDLE VolumeHandle, + OUT EFI_FV_INFO *VolumeInfo + ) +{ + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; +} + +/** + Install a EFI_PEI_FIRMWARE_VOLUME_INFO_PPI instance so the PEI Core will be notified about a new firmware volume. + + This function allocates, initializes, and installs a new EFI_PEI_FIRMWARE_VOLUME_INFO_PPI using + the parameters passed in to initialize the fields of the EFI_PEI_FIRMWARE_VOLUME_INFO_PPI instance. + If the resources can not be allocated for EFI_PEI_FIRMWARE_VOLUME_INFO_PPI, then ASSERT(). + If the EFI_PEI_FIRMWARE_VOLUME_INFO_PPI can not be installed, then ASSERT(). + + + @param FvFormat Unique identifier of the format of the memory-mapped + firmware volume. This parameter is optional and + may be NULL. If NULL is specified, the + EFI_FIRMWARE_FILE_SYSTEM2_GUID format is assumed. + @param FvInfo Points to a buffer which allows the + EFI_PEI_FIRMWARE_VOLUME_PPI to process the volume. + The format of this buffer is specific to the FvFormat. + For memory-mapped firmware volumes, this typically + points to the first byte of the firmware volume. + @param FvInfoSize The size, in bytes, of FvInfo. For memory-mapped + firmware volumes, this is typically the size of + the firmware volume. + @param ParentFvName If the new firmware volume originated from a file + in a different firmware volume, then this parameter + specifies the GUID name of the originating firmware + volume. Otherwise, this parameter must be NULL. + @param ParentFileName If the new firmware volume originated from a file + in a different firmware volume, then this parameter + specifies the GUID file name of the originating + firmware file. Otherwise, this parameter must be NULL. +**/ +VOID +EFIAPI +PeiServicesInstallFvInfoPpi ( + IN CONST EFI_GUID *FvFormat, OPTIONAL + IN CONST VOID *FvInfo, + IN UINT32 FvInfoSize, + IN CONST EFI_GUID *ParentFvName, OPTIONAL + IN CONST EFI_GUID *ParentFileName OPTIONAL + ) +{ + ASSERT (FALSE); + return; +} + diff --git a/CdeEmuPkg/EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf b/CdeEmuPkg/EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf new file mode 100644 index 00000000000..d59812aeef2 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/SecPeiServicesLib/SecPeiServicesLib.inf @@ -0,0 +1,44 @@ +## @file +# PEI Services Library implementation. +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SecPeiServicesLib + FILE_GUID = E3E4A441-8465-0F41-8AF4-F67EBE984099 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeiServicesLib|SEC PEIM PEI_CORE + PI_SPECIFICATION_VERSION = 0x0001000A + +# +# VALID_ARCHITECTURES = IA32 X64 EBC (EBC is for build only) +# + +[Sources] + PeiServicesLib.c + FwVol.c + + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + DebugLib + BaseMemoryLib + PpiListLib + +[Pcd] + gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage + + + + + diff --git a/CdeEmuPkg/EmulatorPkg/Library/SecPpiListLib/PpiListLib.c b/CdeEmuPkg/EmulatorPkg/Library/SecPpiListLib/PpiListLib.c new file mode 100644 index 00000000000..8bccbb45583 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/SecPpiListLib/PpiListLib.c @@ -0,0 +1,11 @@ +/*++ @file + +Copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +CONST EFI_PEI_PPI_DESCRIPTOR *gPpiList = NULL; + diff --git a/CdeEmuPkg/EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf b/CdeEmuPkg/EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf new file mode 100644 index 00000000000..ba77826ad3e --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/SecPpiListLib/SecPpiListLib.inf @@ -0,0 +1,26 @@ +## @file +# Place thunk PPI in HOB. +# +# Copyright (c) 2007 - 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 = SecPpiListLib + FILE_GUID = F950E820-0457-8143-86AD-30E4A45FD4BF + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PpiListLib|SEC BASE USER_DEFINED + +[Sources] + PpiListLib.c + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + diff --git a/CdeEmuPkg/EmulatorPkg/Library/SmbiosLib/SmbiosLib.c b/CdeEmuPkg/EmulatorPkg/Library/SmbiosLib/SmbiosLib.c new file mode 100644 index 00000000000..1e9a068e1c7 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/SmbiosLib/SmbiosLib.c @@ -0,0 +1,346 @@ +/** @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 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + + +EFI_SMBIOS_PROTOCOL *gSmbios = NULL; + + +/** + 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 + ) +{ + EFI_STATUS Status; + UINTN Index; + + if (Template == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = EFI_SUCCESS; + + for (Index = 0; Template[Index].Entry != NULL; Index++) { + Status = SmbiosLibCreateEntry (Template[Index].Entry, Template[Index].StringArray); + } + + return Status; +} + + + +/** + 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 + }; + + ... + CreateSmbiosEntry ( + (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. + +**/ +EFI_STATUS +EFIAPI +SmbiosLibCreateEntry ( + IN SMBIOS_STRUCTURE *SmbiosEntry, + IN CHAR8 **StringArray + ) +{ + EFI_STATUS Status; + EFI_SMBIOS_HANDLE SmbiosHandle; + EFI_SMBIOS_TABLE_HEADER *Record; + UINTN Index; + UINTN StringSize; + UINTN Size; + CHAR8 *Str; + + // Calculate the size of the fixed record and optional string pack + Size = SmbiosEntry->Length; + if (StringArray == NULL) { + Size += 2; // Min string section is double null + } else if (StringArray[0] == NULL) { + Size += 2; // Min string section is double null + } else { + for (Index = 0; StringArray[Index] != NULL; Index++) { + StringSize = AsciiStrSize (StringArray[Index]); + Size += StringSize; + } + // 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, SmbiosEntry, SmbiosEntry->Length); + + if (StringArray != NULL) { + // Append string pack + Str = ((CHAR8 *)Record) + Record->Length; + for (Index = 0; StringArray[Index] != NULL; Index++) { + StringSize = AsciiStrSize (StringArray[Index]); + CopyMem (Str, StringArray[Index], StringSize); + Str += StringSize; + } + *Str = 0; + } + + SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; + Status = gSmbios->Add ( + gSmbios, + gImageHandle, + &SmbiosHandle, + Record + ); + + FreePool (Record); + return Status; +} + + + +/** + 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 + ) +{ + UINTN StringIndex; + + if (String == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (*String == '\0') { + // A string with no data is not legal in SMBIOS + return EFI_INVALID_PARAMETER; + } + + StringIndex = StringNumber; + return gSmbios->UpdateString (gSmbios, &SmbiosHandle, &StringIndex, 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 + ) +{ + EFI_STATUS Status; + UINTN StringIndex; + CHAR8 *Ascii; + + if (String == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (*String == '\0') { + // A string with no data is not legal in SMBIOS + return EFI_INVALID_PARAMETER; + } + + Ascii = AllocateZeroPool (StrSize (String)); + if (Ascii == NULL) { + return EFI_OUT_OF_RESOURCES; + } + UnicodeStrToAsciiStrS (String, Ascii, StrSize (String)); + + StringIndex = StringNumber; + Status = gSmbios->UpdateString (gSmbios, &SmbiosHandle, &StringIndex, Ascii); + + FreePool (Ascii); + return Status; +} + + +/** + 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 + ) +{ + CHAR8 *Data; + UINTN Match; + + Data = (CHAR8 *)Header + Header->Length; + for (Match = 1;!(*Data == 0 && *(Data+1) == 0); ) { + if (StringNumber == Match) { + return Data; + } + Data++; + if (*(Data - 1) == '\0') { + Match++; + } + } + + return NULL; +} + + +/** + 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 + ) +{ + EFI_STATUS Status; + EFI_SMBIOS_TABLE_HEADER *Record; + UINTN Match; + + Match = 0; + *SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; + do { + Status = gSmbios->GetNext (gSmbios, SmbiosHandle, &Type, &Record, NULL); + if (!EFI_ERROR (Status)) { + if (Match == Instance) { + return (SMBIOS_STRUCTURE *)Record; + } + Match++; + } + } while (!EFI_ERROR (Status)); + + return NULL; +} + + +/** + 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 + ) +{ + return gSmbios->Remove (gSmbios, SmbiosHandle); +} + + + +/** + + @param ImageHandle ImageHandle of the loaded driver. + @param SystemTable Pointer to the EFI System Table. + + @retval EFI_SUCCESS Register successfully. + @retval EFI_OUT_OF_RESOURCES No enough memory to register this handler. +**/ +EFI_STATUS +EFIAPI +SmbiosLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&gSmbios); +} + diff --git a/CdeEmuPkg/EmulatorPkg/Library/SmbiosLib/SmbiosLib.inf b/CdeEmuPkg/EmulatorPkg/Library/SmbiosLib/SmbiosLib.inf new file mode 100644 index 00000000000..49d818600ed --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/SmbiosLib/SmbiosLib.inf @@ -0,0 +1,42 @@ +## @file +# SMBIOS Library +# +# Copyright (c) 2012, Apple Inc. All rights reserved. +# Portions copyright (c) 2006 - 2010, Intel Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SmbiosLib + FILE_GUID = 881863A2-09FD-3E44-8D62-7AE038D03747 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = SmbiosLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_APPLICATION UEFI_DRIVER + + CONSTRUCTOR = SmbiosLibConstructor + + +[Sources] + SmbiosLib.c + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiLib + +[Protocols] + gEfiSmbiosProtocolGuid + +[Depex] + gEfiSmbiosProtocolGuid diff --git a/CdeEmuPkg/EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.c b/CdeEmuPkg/EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.c new file mode 100644 index 00000000000..12c789233c1 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.c @@ -0,0 +1,70 @@ +/** @file + Emulator Thunk to abstract OS services from pure EFI code + + Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+ Copyright (c) 2011, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + + +UINTN gThunkPpiListSize = 0; +EFI_PEI_PPI_DESCRIPTOR *gThunkPpiList = NULL; + + + +EFI_PEI_PPI_DESCRIPTOR * +GetThunkPpiList ( + VOID + ) +{ + UINTN Index; + + if (gThunkPpiList == NULL) { + return NULL; + } + + Index = (gThunkPpiListSize/sizeof (EFI_PEI_PPI_DESCRIPTOR)) - 1; + gThunkPpiList[Index].Flags |= EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + + return gThunkPpiList; +} + + +EFI_STATUS +EFIAPI +AddThunkPpi ( + IN UINTN Flags, + IN EFI_GUID *Guid, + IN VOID *Ppi + ) +{ + UINTN Index; + + gThunkPpiList = ReallocatePool ( + gThunkPpiListSize, + gThunkPpiListSize + sizeof (EFI_PEI_PPI_DESCRIPTOR), + gThunkPpiList + ); + if (gThunkPpiList == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Index = (gThunkPpiListSize/sizeof (EFI_PEI_PPI_DESCRIPTOR)); + gThunkPpiList[Index].Flags = Flags; + gThunkPpiList[Index].Guid = Guid; + gThunkPpiList[Index].Ppi = Ppi; + gThunkPpiListSize += sizeof (EFI_PEI_PPI_DESCRIPTOR); + + return EFI_SUCCESS; +} + + + + + diff --git a/CdeEmuPkg/EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf b/CdeEmuPkg/EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf new file mode 100644 index 00000000000..770947915ec --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/ThunkPpiList/ThunkPpiList.inf @@ -0,0 +1,33 @@ +## @file +# Place thunk PPI in HOB. +# +# Copyright (c) 2007 - 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 = ThunkPpiList + FILE_GUID = 465FDE84-E8B0-B04B-A843-A03F68F617A9 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = MemoryAllocationLib|SEC BASE USER_DEFINED + +[Sources] + ThunkPpiList.c + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + +[BuildOptions] + XCODE:*_*_*_DLINK_PATH == gcc + diff --git a/CdeEmuPkg/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.c b/CdeEmuPkg/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.c new file mode 100644 index 00000000000..05fd8124723 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.c @@ -0,0 +1,137 @@ +/** @file + Emulator Thunk to abstract OS services from pure EFI code + + Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+ Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +#include + + +#define EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE SIGNATURE_32('E','m','u','T') + +typedef struct { + UINTN Signature; + EMU_IO_THUNK_PROTOCOL Data; + BOOLEAN EmuBusDriver; + LIST_ENTRY Link; +} EMU_IO_THUNK_PROTOCOL_DATA; + +LIST_ENTRY mThunkList = INITIALIZE_LIST_HEAD_VARIABLE (mThunkList); + + +EFI_STATUS +EFIAPI +AddThunkProtocol ( + IN EMU_IO_THUNK_PROTOCOL *ThunkIo, + IN CHAR16 *ConfigString, + IN BOOLEAN EmuBusDriver + ) +{ + UINTN Size; + CHAR16 *StartString; + CHAR16 *SubString; + UINTN Instance; + EMU_IO_THUNK_PROTOCOL_DATA *Private; + + if (ThunkIo == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = 0; + Size = StrSize (ConfigString); + StartString = AllocatePool (Size); + if (StartString == NULL) { + return EFI_OUT_OF_RESOURCES; + } + StrCpyS (StartString, Size / sizeof (CHAR16), ConfigString); + while (*StartString != '\0') { + + // + // Find the end of the sub string + // + SubString = StartString; + while (*SubString != '\0' && *SubString != '!') { + SubString++; + } + + if (*SubString == '!') { + // + // Replace token with '\0' to make sub strings. If this is the end + // of the string SubString will already point to NULL. + // + *SubString = '\0'; + SubString++; + } + + Private = AllocatePool (sizeof (EMU_IO_THUNK_PROTOCOL_DATA)); + if (Private == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Private->Signature = EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE; + Private->EmuBusDriver = EmuBusDriver; + + CopyMem (&Private->Data, ThunkIo, sizeof (EMU_IO_THUNK_PROTOCOL)); + Private->Data.Instance = (UINT16)Instance++; + Private->Data.ConfigString = StartString; + + InsertTailList (&mThunkList, &Private->Link); + + // + // Parse Next sub string. This will point to '\0' if we are at the end. + // + StartString = SubString; + } + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +GetNextThunkProtocol ( + IN BOOLEAN EmuBusDriver, + OUT EMU_IO_THUNK_PROTOCOL **Instance OPTIONAL + ) +{ + LIST_ENTRY *Link; + EMU_IO_THUNK_PROTOCOL_DATA *Private; + + if (mThunkList.ForwardLink == &mThunkList) { + // Skip parsing an empty list + return EFI_NOT_FOUND; + } + + for (Link = mThunkList.ForwardLink; Link != &mThunkList; Link = Link->ForwardLink) { + Private = CR (Link, EMU_IO_THUNK_PROTOCOL_DATA, Link, EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE); + if (EmuBusDriver & !Private->EmuBusDriver) { + continue; + } else if (*Instance == NULL) { + // Find 1st match in list + *Instance = &Private->Data; + return EFI_SUCCESS; + } else if (*Instance == &Private->Data) { + // Matched previous call so look for valid next entry + Link = Link->ForwardLink; + if (Link == &mThunkList) { + return EFI_NOT_FOUND; + } + Private = CR (Link, EMU_IO_THUNK_PROTOCOL_DATA, Link, EMU_IO_THUNK_PROTOCOL_DATA_SIGNATURE); + *Instance = &Private->Data; + return EFI_SUCCESS; + } + } + + + return EFI_NOT_FOUND; +} + diff --git a/CdeEmuPkg/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf b/CdeEmuPkg/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf new file mode 100644 index 00000000000..145165a3629 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Library/ThunkProtocolList/ThunkProtocolList.inf @@ -0,0 +1,31 @@ +## @file +# +# Copyright (c) 2007 - 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 = ThunkProtocolList + FILE_GUID = 7833616E-AE0D-594F-870C-80E68682D587 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = MemoryAllocationLib|BASE SEC USER_DEFINED + +[Sources] + ThunkProtocolList.c + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + + + diff --git a/CdeEmuPkg/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml b/CdeEmuPkg/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml new file mode 100644 index 00000000000..a95c8554eae --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/PlatformCI/.azurepipelines/Ubuntu-GCC5.yml @@ -0,0 +1,87 @@ +## @file +# Azure Pipeline build file for building a platform. +# +# Platform: EmulatorPkg +# OS: Ubuntu +# Toolchain: GCC5 +# +# Copyright (c) Microsoft Corporation. +# Copyright (c) 2020, Intel Corporation. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +trigger: + - master + - stable/* +pr: + - master + - stable/* +jobs: + - job: Platform_CI + variables: + package: 'EmulatorPkg' + vm_image: 'ubuntu-18.04' + should_run: false + run_flags: "MAKE_STARTUP_NSH=TRUE" + + #Use matrix to speed up the build process + strategy: + matrix: + EmulatorPkg_X64_DEBUG: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "X64" + Build.Flags: "" + Build.Target: "DEBUG" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_X64_RELEASE: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "X64" + Build.Flags: "" + Build.Target: "RELEASE" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_X64_NOOPT: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "X64" + Build.Flags: "" + Build.Target: "NOOPT" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_X64_FULL_DEBUG: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "X64" + Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE" + Build.Target: "DEBUG" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_X64_FULL_RELEASE: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "X64" + Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE" + Build.Target: "RELEASE" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_X64_FULL_NOOPT: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "X64" + Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE" + Build.Target: "NOOPT" + Run.Flags: $(run_flags) + Run: $(should_run) + + workspace: + clean: all + + pool: + vmImage: $(vm_image) + + steps: + - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml + parameters: + tool_chain_tag: GCC5 + build_pkg: $(package) + build_target: $(Build.Target) + build_arch: $(Build.Arch) + build_file: $(Build.File) + build_flags: $(Build.Flags) + run_flags: $(Run.Flags) diff --git a/CdeEmuPkg/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml b/CdeEmuPkg/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml new file mode 100644 index 00000000000..89513ef40a7 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/PlatformCI/.azurepipelines/Windows-VS2019.yml @@ -0,0 +1,130 @@ +## @file +# Azure Pipeline build file for building a platform. +# +# Platform: EMULATORPKG +# OS: Windows +# Toolchain: VS2019 +# +# Copyright (c) Microsoft Corporation. +# Copyright (c) 2020, Intel Corporation. All rights reserved. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +trigger: + - master + - stable/* +pr: + - master + - stable/* + +jobs: + - job: Platform_CI + variables: + package: 'EmulatorPkg' + vm_image: 'windows-latest' + should_run: true + run_flags: "MAKE_STARTUP_NSH=TRUE" + + #Use matrix to speed up the build process + strategy: + matrix: + EmulatorPkg_X64_DEBUG: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "X64" + Build.Flags: "" + Build.Target: "DEBUG" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_X64_RELEASE: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "X64" + Build.Flags: "" + Build.Target: "RELEASE" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_X64_NOOPT: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "X64" + Build.Flags: "" + Build.Target: "NOOPT" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_IA32_DEBUG: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "IA32 " + Build.Flags: "" + Build.Target: "DEBUG" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_IA32_RELEASE: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "IA32 " + Build.Flags: "" + Build.Target: "RELEASE" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_IA32_NOOPT: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "IA32 " + Build.Flags: "" + Build.Target: "NOOPT" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_X64_FULL_DEBUG: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "X64" + Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE" + Build.Target: "DEBUG" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_X64_FULL_RELEASE: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "X64" + Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE" + Build.Target: "RELEASE" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_X64_FULL_NOOPT: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "X64" + Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE" + Build.Target: "NOOPT" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_IA32_FULL_DEBUG: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "IA32" + Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE" + Build.Target: "DEBUG" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_IA32_FULL_RELEASE: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "IA32" + Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE" + Build.Target: "RELEASE" + Run.Flags: $(run_flags) + Run: $(should_run) + EmulatorPkg_IA32_FULL_NOOPT: + Build.File: "$(package)/PlatformCI/PlatformBuild.py" + Build.Arch: "IA32" + Build.Flags: "BLD_*_SECURE_BOOT_ENABLE=TRUE" + Build.Target: "NOOPT" + Run.Flags: $(run_flags) + Run: $(should_run) + + workspace: + clean: all + + pool: + vmImage: $(vm_image) + + steps: + - template: ../../../.azurepipelines/templates/platform-build-run-steps.yml + parameters: + tool_chain_tag: VS2019 + build_pkg: $(package) + build_target: $(Build.Target) + build_arch: $(Build.Arch) + build_file: $(Build.File) + build_flags: $(Build.Flags) + run_flags: $(Run.Flags) diff --git a/CdeEmuPkg/EmulatorPkg/PlatformCI/PlatformBuild.py b/CdeEmuPkg/EmulatorPkg/PlatformCI/PlatformBuild.py new file mode 100644 index 00000000000..37759a661e5 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/PlatformCI/PlatformBuild.py @@ -0,0 +1,272 @@ +# @file +# Script to Build EmulatorPkg UEFI firmware +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +import os +import logging +import io + +from edk2toolext.environment import shell_environment +from edk2toolext.environment.uefi_build import UefiBuilder +from edk2toolext.invocables.edk2_platform_build import BuildSettingsManager +from edk2toolext.invocables.edk2_setup import SetupSettingsManager, RequiredSubmodule +from edk2toolext.invocables.edk2_update import UpdateSettingsManager +from edk2toolext.invocables.edk2_pr_eval import PrEvalSettingsManager +from edk2toollib.utility_functions import RunCmd +from edk2toollib.utility_functions import GetHostInfo + +# ####################################################################################### # +# Common Configuration # +# ####################################################################################### # + + +class CommonPlatform(): + ''' Common settings for this platform. Define static data here and use + for the different parts of stuart + ''' + PackagesSupported = ("EmulatorPkg",) + ArchSupported = ("X64", "IA32") + TargetsSupported = ("DEBUG", "RELEASE", "NOOPT") + Scopes = ('emulatorpkg', 'edk2-build') + WorkspaceRoot = os.path.realpath(os.path.join( + os.path.dirname(os.path.abspath(__file__)), "..", "..")) + + # ####################################################################################### # + # Configuration for Update & Setup # + # ####################################################################################### # + + +class SettingsManager(UpdateSettingsManager, SetupSettingsManager, PrEvalSettingsManager): + + def GetPackagesSupported(self): + ''' return iterable of edk2 packages supported by this build. + These should be edk2 workspace relative paths ''' + return CommonPlatform.PackagesSupported + + def GetArchitecturesSupported(self): + ''' return iterable of edk2 architectures supported by this build ''' + return CommonPlatform.ArchSupported + + def GetTargetsSupported(self): + ''' return iterable of edk2 target tags supported by this build ''' + return CommonPlatform.TargetsSupported + + def GetRequiredSubmodules(self): + ''' return iterable containing RequiredSubmodule objects. + If no RequiredSubmodules return an empty iterable + ''' + rs = [] + # intentionally declare this one with recursive false to avoid overhead + rs.append(RequiredSubmodule( + "CryptoPkg/Library/OpensslLib/openssl", False)) + + # To avoid maintenance of this file for every new submodule + # lets just parse the .gitmodules and add each if not already in list. + # The GetRequiredSubmodules is designed to allow a build to optimize + # the desired submodules but it isn't necessary for this repository. + result = io.StringIO() + ret = RunCmd("git", "config --file .gitmodules --get-regexp path", workingdir=self.GetWorkspaceRoot(), outstream=result) + # Cmd output is expected to look like: + # submodule.CryptoPkg/Library/OpensslLib/openssl.path CryptoPkg/Library/OpensslLib/openssl + # submodule.SoftFloat.path ArmPkg/Library/ArmSoftFloatLib/berkeley-softfloat-3 + if ret == 0: + for line in result.getvalue().splitlines(): + _, _, path = line.partition(" ") + if path is not None: + if path not in [x.path for x in rs]: + rs.append(RequiredSubmodule(path, True)) # add it with recursive since we don't know + return rs + + def SetArchitectures(self, list_of_requested_architectures): + ''' Confirm the requests architecture list is valid and configure SettingsManager + to run only the requested architectures. + + Raise Exception if a list_of_requested_architectures is not supported + ''' + unsupported = set(list_of_requested_architectures) - \ + set(self.GetArchitecturesSupported()) + if(len(unsupported) > 0): + errorString = ( + "Unsupported Architecture Requested: " + " ".join(unsupported)) + logging.critical(errorString) + raise Exception(errorString) + self.ActualArchitectures = list_of_requested_architectures + + def GetWorkspaceRoot(self): + ''' get WorkspacePath ''' + return CommonPlatform.WorkspaceRoot + + def GetActiveScopes(self): + ''' return tuple containing scopes that should be active for this process ''' + return CommonPlatform.Scopes + + def FilterPackagesToTest(self, changedFilesList: list, potentialPackagesList: list) -> list: + ''' Filter other cases that this package should be built + based on changed files. This should cover things that can't + be detected as dependencies. ''' + build_these_packages = [] + possible_packages = potentialPackagesList.copy() + for f in changedFilesList: + # BaseTools files that might change the build + if "BaseTools" in f: + if os.path.splitext(f) not in [".txt", ".md"]: + build_these_packages = possible_packages + break + # if the azure pipeline platform template file changed + if "platform-build-run-steps.yml" in f: + build_these_packages = possible_packages + break + return build_these_packages + + def GetPlatformDscAndConfig(self) -> tuple: + ''' If a platform desires to provide its DSC then Policy 4 will evaluate if + any of the changes will be built in the dsc. + + The tuple should be (, ) + ''' + return (os.path.join("EmulatorPkg", "EmulatorPkg.dsc"), {}) + + # ####################################################################################### # + # Actual Configuration for Platform Build # + # ####################################################################################### # + + +class PlatformBuilder(UefiBuilder, BuildSettingsManager): + def __init__(self): + UefiBuilder.__init__(self) + + def AddCommandLineOptions(self, parserObj): + ''' Add command line options to the argparser ''' + parserObj.add_argument('-a', "--arch", dest="build_arch", type=str, default="X64", + help="Optional - architecture to build. IA32 will use IA32 for Pei & Dxe. " + "X64 will use X64 for both PEI and DXE.") + + def RetrieveCommandLineOptions(self, args): + ''' Retrieve command line options from the argparser ''' + + shell_environment.GetBuildVars().SetValue( + "TARGET_ARCH", args.build_arch.upper(), "From CmdLine") + shell_environment.GetBuildVars().SetValue( + "ACTIVE_PLATFORM", "EmulatorPkg/EmulatorPkg.dsc", "From CmdLine") + + def GetWorkspaceRoot(self): + ''' get WorkspacePath ''' + return CommonPlatform.WorkspaceRoot + + def GetPackagesPath(self): + ''' Return a list of workspace relative paths that should be mapped as edk2 PackagesPath ''' + return () + + def GetActiveScopes(self): + ''' return tuple containing scopes that should be active for this process ''' + return CommonPlatform.Scopes + + def GetName(self): + ''' Get the name of the repo, platform, or product being build ''' + ''' Used for naming the log file, among others ''' + + # check the startup nsh flag and if set then rename the log file. + # this helps in CI so we don't overwrite the build log since running + # uses the stuart_build command. + if(shell_environment.GetBuildVars().GetValue("MAKE_STARTUP_NSH", "FALSE") == "TRUE"): + return "EmulatorPkg_With_Run" + return "EmulatorPkg" + + def GetLoggingLevel(self, loggerType): + ''' Get the logging level for a given type + base == lowest logging level supported + con == Screen logging + txt == plain text file logging + md == markdown file logging + ''' + return logging.DEBUG + + def SetPlatformEnv(self): + logging.debug("PlatformBuilder SetPlatformEnv") + self.env.SetValue("PRODUCT_NAME", "EmulatorPkg", "Platform Hardcoded") + self.env.SetValue("TOOL_CHAIN_TAG", "VS2019", "Default Toolchain") + + # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture + # requested to be built when building VS2019 or VS2017 + if self.env.GetValue("TOOL_CHAIN_TAG") == "VS2019" or self.env.GetValue("TOOL_CHAIN_TAG") == "VS2017": + key = self.env.GetValue("TOOL_CHAIN_TAG") + "_HOST" + if self.env.GetValue("TARGET_ARCH") == "IA32": + shell_environment.ShellEnvironment().set_shell_var(key, "x86") + elif self.env.GetValue("TARGET_ARCH") == "X64": + shell_environment.ShellEnvironment().set_shell_var(key, "x64") + + # Add support for using the correct Platform Headers, tools, and Libs based on emulator architecture + # requested to be built when building on linux. + if GetHostInfo().os.upper() == "LINUX": + self.ConfigureLinuxDLinkPath() + + if GetHostInfo().os.upper() == "WINDOWS": + self.env.SetValue("BLD_*_WIN_HOST_BUILD", "TRUE", + "Trigger Windows host build") + + self.env.SetValue("MAKE_STARTUP_NSH", "FALSE", "Default to false") + + # I don't see what this does but it is in build.sh + key = "BLD_*_BUILD_" + self.env.GetValue("TARGET_ARCH") + self.env.SetValue(key, "TRUE", "match script in build.sh") + return 0 + + def PlatformPreBuild(self): + return 0 + + def PlatformPostBuild(self): + return 0 + + def FlashRomImage(self): + ''' Use the FlashRom Function to run the emulator. This gives an easy stuart command line to + activate the emulator. ''' + + OutputPath = os.path.join(self.env.GetValue( + "BUILD_OUTPUT_BASE"), self.env.GetValue("TARGET_ARCH")) + + if (self.env.GetValue("MAKE_STARTUP_NSH") == "TRUE"): + f = open(os.path.join(OutputPath, "startup.nsh"), "w") + f.write("BOOT SUCCESS !!! \n") + # add commands here + f.write("reset\n") + f.close() + + if GetHostInfo().os.upper() == "WINDOWS": + cmd = "WinHost.exe" + elif GetHostInfo().os.upper() == "LINUX": + cmd = "./Host" + else: + logging.critical("Unsupported Host") + return -1 + return RunCmd(cmd, "", workingdir=OutputPath) + + def ConfigureLinuxDLinkPath(self): + ''' + logic copied from build.sh to setup the correct libraries + ''' + if self.env.GetValue("TARGET_ARCH") == "IA32": + LIB_NAMES = ["ld-linux.so.2", "libdl.so.2 crt1.o", "crti.o crtn.o"] + LIB_SEARCH_PATHS = ["/usr/lib/i386-linux-gnu", + "/usr/lib32", "/lib32", "/usr/lib", "/lib"] + elif self.env.GetValue("TARGET_ARCH") == "X64": + LIB_NAMES = ["ld-linux-x86-64.so.2", + "libdl.so.2", "crt1.o", "crti.o", "crtn.o"] + LIB_SEARCH_PATHS = ["/usr/lib/x86_64-linux-gnu", + "/usr/lib64", "/lib64", "/usr/lib", "/lib"] + + HOST_DLINK_PATHS = "" + for lname in LIB_NAMES: + logging.debug(f"Looking for {lname}") + for dname in LIB_SEARCH_PATHS: + logging.debug(f"In {dname}") + if os.path.isfile(os.path.join(dname, lname)): + logging.debug(f"Found {lname} in {dname}") + HOST_DLINK_PATHS += os.path.join( + os.path.join(dname, lname)) + os.pathsep + break + HOST_DLINK_PATHS = HOST_DLINK_PATHS.rstrip(os.pathsep) + logging.critical(f"Setting HOST_DLINK_PATHS to {HOST_DLINK_PATHS}") + shell_environment.ShellEnvironment().set_shell_var( + "HOST_DLINK_PATHS", HOST_DLINK_PATHS) diff --git a/CdeEmuPkg/EmulatorPkg/PlatformCI/ReadMe.md b/CdeEmuPkg/EmulatorPkg/PlatformCI/ReadMe.md new file mode 100644 index 00000000000..894ad44834d --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/PlatformCI/ReadMe.md @@ -0,0 +1,130 @@ +# EmulatorPkg - Platform CI + +This ReadMe.md describes the Azure DevOps based Platform CI for EmulatorPkg and how +to use the same Pytools based build infrastructure locally. + +## Supported Configuration Details + +This solution for building and running EmulatorPkg has only been validated with Windows 10 +with VS2019 and Ubuntu 18.04 with GCC5 toolchain. Four different firmware builds are +supported and are described below. + +| Configuration name | Architectures | DSC File |Additional Flags | +| :---- | :----- | :---- | :---- | +| IA32 | IA32 | EmulatorPkg.dsc | None | +| X64 | X64 | EmulatorPkg.dsc | None | +| IA32 Full | IA32 | EmulatorPkg.dsc | SECURE_BOOT_ENABLE=TRUE | +| X64 Full | X64 | EmulatorPkg.dsc | SECURE_BOOT_ENABLE=TRUE | + +## EDK2 Developer environment + +- [Python 3.8.x - Download & Install](https://www.python.org/downloads/) +- [GIT - Download & Install](https://git-scm.com/download/) +- [Edk2 Source](https://github.com/tianocore/edk2) +- For building Basetools and other host applications + + ``` bash + sudo apt-get update + sudo apt-get install gcc g++ make uuid-dev + ``` + +- For building ARCH IA32 on X64 Ubuntu 18.04 LTS these steps where needed. + + ``` bash + sudo dpkg --add-architecture i386 + sudo apt-get update + sudo apt-get install libc6-dev:i386 libx11-dev:i386 libxext-dev:i386 lib32gcc-7-dev + ``` + +Note: edksetup, Submodule initialization and manual installation of NASM, iASL, or +the required cross-compiler toolchains are **not** required, this is handled by the +Pytools build system. + +## Building with Pytools for EmulatorPkg + +1. [Optional] Create a Python Virtual Environment - generally once per workspace + + ``` bash + python -m venv + ``` + +2. [Optional] Activate Virtual Environment - each time new shell opened + - Linux + + ```bash + source /bin/activate + ``` + + - Windows + + ``` bash + /Scripts/activate.bat + ``` + +3. Install Pytools - generally once per virtual env or whenever pip-requirements.txt changes + + ``` bash + pip install --upgrade -r pip-requirements.txt + ``` + +4. Initialize & Update Submodules - only when submodules updated + + ``` bash + stuart_setup -c EmulatorPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG= -a + ``` + +5. Initialize & Update Dependencies - only as needed when ext_deps change + + ``` bash + stuart_update -c EmulatorPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG= -a + ``` + +6. Compile the basetools if necessary - only when basetools C source files change + + ``` bash + python BaseTools/Edk2ToolsBuild.py -t + ``` + +7. Compile Firmware + + ``` bash + stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG= -a + ``` + + - use `stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py -h` option to see additional + options like `--clean` + +8. Running Emulator + - You can add `--FlashRom` to the end of your build command and the emulator will run after the + build is complete. + - or use the `--FlashOnly` feature to just run the emulator. + + ``` bash + stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py TOOL_CHAIN_TAG= -a --FlashOnly + ``` + +### Notes + +1. Configuring *ACTIVE_PLATFORM* and *TARGET_ARCH* in Conf/target.txt is **not** required. This + environment is set by PlatformBuild.py based upon the `[-a ]` parameter. + +**NOTE:** Logging the execution output will be in the normal stuart log as well as to your console. + +### Custom Build Options + +**MAKE_STARTUP_NSH=TRUE** will output a *startup.nsh* file to the location mapped as fs0. This is +used in CI in combination with the `--FlashOnly` feature to run the Emulator to the UEFI shell and then execute +the contents of *startup.nsh*. + +### Passing Build Defines + +To pass build defines through _stuart_build_, prepend `BLD_*_`to the define name and pass it on the +command-line. _stuart_build_ currently requires values to be assigned, so add an`=1` suffix for bare defines. +For example, to enable the IP6 Network Stack, the stuart_build command-line would be: + +`stuart_build -c EmulatorPkg/PlatformCI/PlatformBuild.py BLD_*_NETWORK_IP6_ENABLE=1` + +## References + +- [Installing and using Pytools](https://github.com/tianocore/edk2-pytool-extensions/blob/master/docs/using.md#installing) +- More on [python virtual environments](https://docs.python.org/3/library/venv.html) diff --git a/CdeEmuPkg/EmulatorPkg/PlatformSmbiosDxe/PlatformSmbiosDxe.c b/CdeEmuPkg/EmulatorPkg/PlatformSmbiosDxe/PlatformSmbiosDxe.c new file mode 100644 index 00000000000..679f9fdbfc0 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/PlatformSmbiosDxe/PlatformSmbiosDxe.c @@ -0,0 +1,130 @@ +/** @file + Static SMBIOS Table for platform + + + Copyright (c) 2012, Apple Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +#include +#include +#include +#include +#include + +extern SMBIOS_TEMPLATE_ENTRY gSmbiosTemplate[]; + + + +SMBIOS_TABLE_TYPE19 gSmbiosType19Template = { + { EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS, sizeof (SMBIOS_TABLE_TYPE19), 0 }, + 0xffffffff, // StartingAddress; + 0xffffffff, // EndingAddress; + 0, // MemoryArrayHandle; + 1, // PartitionWidth; + 0, // ExtendedStartingAddress; + 0, // ExtendedEndingAddress; +}; + +VOID +CreatePlatformSmbiosMemoryRecords ( + VOID + ) +{ + EFI_PEI_HOB_POINTERS HobPtr; + SMBIOS_STRUCTURE_POINTER Smbios16; + SMBIOS_STRUCTURE_POINTER Smbios17; + EFI_SMBIOS_HANDLE PhyscialMemoryArrayHandle; + EFI_SMBIOS_HANDLE SmbiosHandle; + + Smbios16.Hdr = SmbiosLibGetRecord (EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, 0, &PhyscialMemoryArrayHandle); + if (Smbios16.Hdr == NULL) { + // Only make a Type19 entry if a Type16 entry exists. + return; + } + + Smbios17.Hdr = SmbiosLibGetRecord (EFI_SMBIOS_TYPE_MEMORY_DEVICE, 0, &SmbiosHandle); + if (Smbios17.Hdr == NULL) { + // if type17 exits update with type16 Smbios handle + Smbios17.Type17->MemoryArrayHandle = PhyscialMemoryArrayHandle; + } + + // Generate Type16 records + gSmbiosType19Template.MemoryArrayHandle = PhyscialMemoryArrayHandle; + HobPtr.Raw = GetHobList (); + while ((HobPtr.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, HobPtr.Raw)) != NULL) { + if (HobPtr.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) { + gSmbiosType19Template.ExtendedStartingAddress = HobPtr.ResourceDescriptor->PhysicalStart; + gSmbiosType19Template.ExtendedEndingAddress = + HobPtr.ResourceDescriptor->PhysicalStart + + HobPtr.ResourceDescriptor->ResourceLength - 1; + + SmbiosLibCreateEntry ((SMBIOS_STRUCTURE *)&gSmbiosType19Template, NULL); + } + HobPtr.Raw = GET_NEXT_HOB (HobPtr); + } +} + + +/** + Main entry for this driver. + + @param ImageHandle Image handle this driver. + @param SystemTable Pointer to SystemTable. + + @retval EFI_SUCESS This function always complete successfully. + +**/ +EFI_STATUS +EFIAPI +PlatformSmbiosDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_SMBIOS_HANDLE SmbiosHandle; + SMBIOS_STRUCTURE_POINTER Smbios; + + // Phase 0 - Patch table to make SMBIOS 2.7 structures smaller to conform + // to an early version of the specification. + + // Phase 1 - Initialize SMBIOS tables from template + Status = SmbiosLibInitializeFromTemplate (gSmbiosTemplate); + ASSERT_EFI_ERROR (Status); + + // Phase 2 - Patch SMBIOS table entries + + Smbios.Hdr = SmbiosLibGetRecord (EFI_SMBIOS_TYPE_BIOS_INFORMATION, 0, &SmbiosHandle); + if (Smbios.Type0 != NULL) { + // 64K * (n+1) bytes + Smbios.Type0->BiosSize = (UINT8)DivU64x32 (FixedPcdGet64 (PcdEmuFirmwareFdSize), 64*1024) - 1; + + SmbiosLibUpdateUnicodeString ( + SmbiosHandle, + Smbios.Type0->BiosVersion, + (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString) + ); + SmbiosLibUpdateUnicodeString ( + SmbiosHandle, + Smbios.Type0->BiosReleaseDate, + (CHAR16 *) PcdGetPtr (PcdFirmwareReleaseDateString) + ); + } + + // Phase 3 - Create tables from scratch + + // Create Type 13 record from EFI Variables + // Do we need this record for EFI as the info is available from EFI varaibles + // Also language types don't always match between EFI and SMBIOS + // CreateSmbiosLanguageInformation (1, gSmbiosLangToEfiLang); + + CreatePlatformSmbiosMemoryRecords (); + + return EFI_SUCCESS; +} diff --git a/CdeEmuPkg/EmulatorPkg/PlatformSmbiosDxe/PlatformSmbiosDxe.inf b/CdeEmuPkg/EmulatorPkg/PlatformSmbiosDxe/PlatformSmbiosDxe.inf new file mode 100644 index 00000000000..0f4a1309405 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/PlatformSmbiosDxe/PlatformSmbiosDxe.inf @@ -0,0 +1,50 @@ +## @file +# Platform SMBIOS driver that fills in SMBIOS table entries. +# +# Copyright (c) 2012, Apple Inc. All rights reserved. +# Portions copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatformSmbiosDxe + FILE_GUID = 67FA951E-4FA2-9F4E-A658-4DBD954AC22E + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = PlatformSmbiosDriverEntryPoint + + +[Sources] + SmbiosTable.c + PlatformSmbiosDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + BaseLib + BaseMemoryLib + DebugLib + PcdLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiLib + HobLib + SmbiosLib + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareReleaseDateString + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString + gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang + gEmulatorPkgTokenSpaceGuid.PcdEmuMemorySize + gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareFdSize + +[Depex] + TRUE diff --git a/CdeEmuPkg/EmulatorPkg/PlatformSmbiosDxe/SmbiosTable.c b/CdeEmuPkg/EmulatorPkg/PlatformSmbiosDxe/SmbiosTable.c new file mode 100644 index 00000000000..83997ac0047 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/PlatformSmbiosDxe/SmbiosTable.c @@ -0,0 +1,442 @@ +/** @file + Static SMBIOS Table for platform + + Note SMBIOS 2.7.1 Required structures: + BIOS Information (Type 0) + System Information (Type 1) + System Enclosure (Type 3) + Processor Information (Type 4) - CPU Driver + Cache Information (Type 7) - For cache that is external to processor + System Slots (Type 9) - If system has slots + Physical Memory Array (Type 16) + Memory Device (Type 17) - For each socketed system-memory Device + Memory Array Mapped Address (Type 19) - One per contiguous block per Physical Memroy Array + System Boot Information (Type 32) + + Copyright (c) 2012, Apple Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + + +SMBIOS_TABLE_TYPE0 gSmbiosType0Template = { + { EFI_SMBIOS_TYPE_BIOS_INFORMATION, sizeof (SMBIOS_TABLE_TYPE0), 0 }, + 1, // Vendor String + 2, // BiosVersion String + 0xE000, // BiosSegment + 3, // BiosReleaseDate String + 0x7F, // BiosSize + { // BiosCharacteristics + 0, // Reserved :2; ///< Bits 0-1. + 0, // Unknown :1; + 0, // BiosCharacteristicsNotSupported :1; + 0, // IsaIsSupported :1; + 0, // McaIsSupported :1; + 0, // EisaIsSupported :1; + 1, // PciIsSupported :1; + 0, // PcmciaIsSupported :1; + 0, // PlugAndPlayIsSupported :1; + 0, // ApmIsSupported :1; + 1, // BiosIsUpgradable :1; + 1, // BiosShadowingAllowed :1; + 0, // VlVesaIsSupported :1; + 0, // EscdSupportIsAvailable :1; + 0, // BootFromCdIsSupported :1; + 1, // SelectableBootIsSupported :1; + 0, // RomBiosIsSocketed :1; + 0, // BootFromPcmciaIsSupported :1; + 0, // EDDSpecificationIsSupported :1; + 0, // JapaneseNecFloppyIsSupported :1; + 0, // JapaneseToshibaFloppyIsSupported :1; + 0, // Floppy525_360IsSupported :1; + 0, // Floppy525_12IsSupported :1; + 0, // Floppy35_720IsSupported :1; + 0, // Floppy35_288IsSupported :1; + 0, // PrintScreenIsSupported :1; + 0, // Keyboard8042IsSupported :1; + 0, // SerialIsSupported :1; + 0, // PrinterIsSupported :1; + 0, // CgaMonoIsSupported :1; + 0, // NecPc98 :1; + 0 // ReservedForVendor :32; ///< Bits 32-63. Bits 32-47 reserved for BIOS vendor + ///< and bits 48-63 reserved for System Vendor. + }, + { // BIOSCharacteristicsExtensionBytes[] + 0x81, // AcpiIsSupported :1; + // UsbLegacyIsSupported :1; + // AgpIsSupported :1; + // I2OBootIsSupported :1; + // Ls120BootIsSupported :1; + // AtapiZipDriveBootIsSupported :1; + // Boot1394IsSupported :1; + // SmartBatteryIsSupported :1; + // BIOSCharacteristicsExtensionBytes[1] + 0x0a, // BiosBootSpecIsSupported :1; + // FunctionKeyNetworkBootIsSupported :1; + // TargetContentDistributionEnabled :1; + // UefiSpecificationSupported :1; + // VirtualMachineSupported :1; + // ExtensionByte2Reserved :3; + }, + 0x00, // SystemBiosMajorRelease + 0x01, // SystemBiosMinorRelease + 0xFF, // EmbeddedControllerFirmwareMajorRelease + 0xFF, // EmbeddedControllerFirmwareMinorRelease +}; +CHAR8 *gSmbiosType0Strings[] = { + "http://www.tianocore.org/edk2/", // Vendor String + __TIME__, // BiosVersion String + __DATE__, // BiosReleaseDate String + NULL +}; + +SMBIOS_TABLE_TYPE1 gSmbiosType1Template = { + { EFI_SMBIOS_TYPE_SYSTEM_INFORMATION, sizeof (SMBIOS_TABLE_TYPE1), 0 }, + 1, // Manufacturer String + 2, // ProductName String + 3, // Version String + 4, // SerialNumber String + { 0x25EF0280, 0xEC82, 0x42B0, { 0x8F, 0xB6, 0x10, 0xAD, 0xCC, 0xC6, 0x7C, 0x02 } }, + SystemWakeupTypePowerSwitch, + 5, // SKUNumber String + 6, // Family String +}; +CHAR8 *gSmbiosType1Strings[] = { + "http://www.tianocore.org/edk2/", + "EmulatorPkg", + "1.0", + "System Serial#", + "System SKU#", + "edk2", + NULL +}; + +SMBIOS_TABLE_TYPE2 gSmbiosType2Template = { + { EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION, sizeof (SMBIOS_TABLE_TYPE2), 0 }, + 1, // Manufacturer String + 2, // ProductName String + 3, // Version String + 4, // SerialNumber String + 5, // AssetTag String + { // FeatureFlag + 1, // Motherboard :1; + 0, // RequiresDaughterCard :1; + 0, // Removable :1; + 0, // Replaceable :1; + 0, // HotSwappable :1; + 0, // Reserved :3; + }, + 6, // LocationInChassis String + 0, // ChassisHandle; + BaseBoardTypeMotherBoard, // BoardType; + 0, // NumberOfContainedObjectHandles; + { 0 } // ContainedObjectHandles[1]; +}; +CHAR8 *gSmbiosType2Strings[] = { + "http://www.tianocore.org/edk2/", + "EmulatorPkg", + "1.0", + "Base Board Serial#", + "Base Board Asset Tag#", + "Part Component", + NULL +}; + +SMBIOS_TABLE_TYPE3 gSmbiosType3Template = { + { EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE, sizeof (SMBIOS_TABLE_TYPE3), 0 }, + 1, // Manufacturer String + MiscChassisTypeLapTop, // Type; + 2, // Version String + 3, // SerialNumber String + 4, // AssetTag String + ChassisStateSafe, // BootupState; + ChassisStateSafe, // PowerSupplyState; + ChassisStateSafe, // ThermalState; + ChassisSecurityStatusNone,// SecurityStatus; + { 0, 0, 0, 0 }, // OemDefined[4]; + 0, // Height; + 0, // NumberofPowerCords; + 0, // ContainedElementCount; + 0, // ContainedElementRecordLength; + { { 0 } }, // ContainedElements[1]; +}; +CHAR8 *gSmbiosType3Strings[] = { + "http://www.tianocore.org/edk2/", + "EmulatorPkg", + "Chassis Board Serial#", + "Chassis Board Asset Tag#", + NULL +}; + +SMBIOS_TABLE_TYPE8 gSmbiosType8Template1 = { + { EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, sizeof (SMBIOS_TABLE_TYPE8), 0 }, + 0, // InternalReferenceDesignator String + PortConnectorTypeNone, // InternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + 1, // ExternalReferenceDesignator String + PortConnectorTypeNone, // ExternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + PortTypeOther, // PortType; ///< The enumeration value from MISC_PORT_TYPE. +}; +CHAR8 *gSmbiosType8Strings1[] = { + "Mini DisplayPort", + NULL +}; + +SMBIOS_TABLE_TYPE8 gSmbiosType8Template2 = { + { EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, sizeof (SMBIOS_TABLE_TYPE8), 0 }, + 0, // InternalReferenceDesignator String + PortConnectorTypeNone, // InternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + 1, // ExternalReferenceDesignator String + PortConnectorTypeNone, // ExternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + PortTypeFireWire, // PortType; ///< The enumeration value from MISC_PORT_TYPE. +}; +CHAR8 *gSmbiosType8Strings2[] = { + "FireWire 800", + NULL +}; + + +SMBIOS_TABLE_TYPE8 gSmbiosType8Template3 = { + { EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, sizeof (SMBIOS_TABLE_TYPE8), 0 }, + 0, // InternalReferenceDesignator String + PortConnectorTypeNone, // InternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + 1, // ExternalReferenceDesignator String + PortConnectorTypeRJ45, // ExternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + PortTypeNetworkPort, // PortType; ///< The enumeration value from MISC_PORT_TYPE. +}; +CHAR8 *gSmbiosType8Strings3[] = { + "Ethernet", + NULL +}; + +SMBIOS_TABLE_TYPE8 gSmbiosType8Template4 = { + { EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, sizeof (SMBIOS_TABLE_TYPE8), 0 }, + 0, // InternalReferenceDesignator String + PortConnectorTypeNone, // InternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + 1, // ExternalReferenceDesignator String + PortConnectorTypeUsb, // ExternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + PortTypeUsb, // PortType; ///< The enumeration value from MISC_PORT_TYPE. +}; +CHAR8 *gSmbiosType8Strings4[] = { + "USB0", + NULL +}; + +SMBIOS_TABLE_TYPE8 gSmbiosType8Template5 = { + { EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, sizeof (SMBIOS_TABLE_TYPE8), 0 }, + 0, // InternalReferenceDesignator String + PortConnectorTypeNone, // InternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + 1, // ExternalReferenceDesignator String + PortConnectorTypeUsb, // ExternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + PortTypeUsb, // PortType; ///< The enumeration value from MISC_PORT_TYPE. +}; +CHAR8 *gSmbiosType8Strings5[] = { + "USB1", + NULL +}; + +SMBIOS_TABLE_TYPE8 gSmbiosType8Template6 = { + { EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, sizeof (SMBIOS_TABLE_TYPE8), 0 }, + 0, // InternalReferenceDesignator String + PortConnectorTypeNone, // InternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + 1, // ExternalReferenceDesignator String + PortConnectorTypeUsb, // ExternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + PortTypeUsb, // PortType; ///< The enumeration value from MISC_PORT_TYPE. +}; +CHAR8 *gSmbiosType8Strings6[] = { + "USB2", + NULL +}; + +SMBIOS_TABLE_TYPE8 gSmbiosType8Template7 = { + { EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, sizeof (SMBIOS_TABLE_TYPE8), 0 }, + 0, // InternalReferenceDesignator String + PortConnectorTypeNone, // InternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + 1, // ExternalReferenceDesignator String + PortConnectorTypeUsb, // ExternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + PortTypeUsb, // PortType; ///< The enumeration value from MISC_PORT_TYPE. +}; +CHAR8 *gSmbiosType8Strings7[] = { + "USB3", + NULL +}; + +SMBIOS_TABLE_TYPE8 gSmbiosType8Template8 = { + { EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, sizeof (SMBIOS_TABLE_TYPE8), 0 }, + 0, // InternalReferenceDesignator String + PortConnectorTypeNone, // InternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + 1, // ExternalReferenceDesignator String + PortConnectorTypeHeadPhoneMiniJack, // ExternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + PortTypeAudioPort, // PortType; ///< The enumeration value from MISC_PORT_TYPE. +}; +CHAR8 *gSmbiosType8Strings8[] = { + "Audio Line In", + NULL +}; + +SMBIOS_TABLE_TYPE8 gSmbiosType8Template9 = { + { EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, sizeof (SMBIOS_TABLE_TYPE8), 0 }, + 0, // InternalReferenceDesignator String + PortConnectorTypeNone, // InternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + 1, // ExternalReferenceDesignator String + PortConnectorTypeHeadPhoneMiniJack, // ExternalConnectorType; ///< The enumeration value from MISC_PORT_CONNECTOR_TYPE. + PortTypeAudioPort, // PortType; ///< The enumeration value from MISC_PORT_TYPE. +}; +CHAR8 *gSmbiosType8Strings9[] = { + "Audio Line Out", + NULL +}; + +SMBIOS_TABLE_TYPE9 gSmbiosType9Template = { + { EFI_SMBIOS_TYPE_SYSTEM_SLOTS, sizeof (SMBIOS_TABLE_TYPE9), 0 }, + 1, // SlotDesignation String + SlotTypeOther, // SlotType; ///< The enumeration value from MISC_SLOT_TYPE. + SlotDataBusWidthOther, // SlotDataBusWidth; ///< The enumeration value from MISC_SLOT_DATA_BUS_WIDTH. + SlotUsageAvailable, // CurrentUsage; ///< The enumeration value from MISC_SLOT_USAGE. + SlotLengthOther, // SlotLength; ///< The enumeration value from MISC_SLOT_LENGTH. + 0, // SlotID; + { // SlotCharacteristics1; + 1, // CharacteristicsUnknown :1; + 0, // Provides50Volts :1; + 0, // Provides33Volts :1; + 0, // SharedSlot :1; + 0, // PcCard16Supported :1; + 0, // CardBusSupported :1; + 0, // ZoomVideoSupported :1; + 0, // ModemRingResumeSupported:1; + }, + { // SlotCharacteristics2; + 0, // PmeSignalSupported :1; + 0, // HotPlugDevicesSupported :1; + 0, // SmbusSignalSupported :1; + 0, // Reserved :5; ///< Set to 0. + }, + 0, // SegmentGroupNum; + 0, // BusNum; + 0, // DevFuncNum; +}; +CHAR8 *gSmbiosType9Strings[] = { + "SD Card", + NULL +}; + +SMBIOS_TABLE_TYPE11 gSmbiosType11Template = { + { EFI_SMBIOS_TYPE_OEM_STRINGS, sizeof (SMBIOS_TABLE_TYPE11), 0 }, + 1 // StringCount +}; +CHAR8 *gSmbiosType11Strings[] = { + "https://svn.code.sf.net/p/edk2/code/trunk/edk2/EmulatorPkg/", + NULL +}; + + +SMBIOS_TABLE_TYPE12 gSmbiosType12Template = { + { EFI_SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS, sizeof (SMBIOS_TABLE_TYPE12), 0 }, + 1 // StringCount +}; +CHAR8 *gSmbiosType12Strings[] = { + "https://svn.code.sf.net/p/edk2/code/trunk/edk2/EmulatorPkg/EmulatorPkg.dsc", + NULL +}; + +SMBIOS_TABLE_TYPE16 gSmbiosType16Template = { + { EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, sizeof (SMBIOS_TABLE_TYPE16), 0 }, + MemoryArrayLocationSystemBoard, // Location; ///< The enumeration value from MEMORY_ARRAY_LOCATION. + MemoryArrayUseSystemMemory, // Use; ///< The enumeration value from MEMORY_ARRAY_USE. + MemoryErrorCorrectionUnknown, // MemoryErrorCorrection; ///< The enumeration value from MEMORY_ERROR_CORRECTION. + 0x80000000, // MaximumCapacity; + 0xFFFE, // MemoryErrorInformationHandle; + 1, // NumberOfMemoryDevices; + 0x3fffffffffffffffULL, // ExtendedMaximumCapacity; +}; + +SMBIOS_TABLE_TYPE17 gSmbiosType17Template = { + { EFI_SMBIOS_TYPE_MEMORY_DEVICE, sizeof (SMBIOS_TABLE_TYPE17), 0 }, + 0, // MemoryArrayHandle; + 0xFFFE, // MemoryErrorInformationHandle; + 0xFFFF, // TotalWidth; + 0xFFFF, // DataWidth; + 0xFFFF, // Size; + MemoryFormFactorUnknown, // FormFactor; ///< The enumeration value from MEMORY_FORM_FACTOR. + 0xff, // DeviceSet; + 1, // DeviceLocator String + 2, // BankLocator String + MemoryTypeDram, // MemoryType; ///< The enumeration value from MEMORY_DEVICE_TYPE. + { // TypeDetail; + 0, // Reserved :1; + 0, // Other :1; + 1, // Unknown :1; + 0, // FastPaged :1; + 0, // StaticColumn :1; + 0, // PseudoStatic :1; + 0, // Rambus :1; + 0, // Synchronous :1; + 0, // Cmos :1; + 0, // Edo :1; + 0, // WindowDram :1; + 0, // CacheDram :1; + 0, // Nonvolatile :1; + 0, // Registered :1; + 0, // Unbuffered :1; + 0, // Reserved1 :1; + }, + 0, // Speed; + 3, // Manufacturer String + 0, // SerialNumber String + 0, // AssetTag String + 0, // PartNumber String + 0, // Attributes; + 0, // ExtendedSize; + 0, // ConfiguredMemoryClockSpeed; +}; +CHAR8 *gSmbiosType17Strings[] = { + "OS Virtual Memory", + "malloc", + "OSV", + NULL +}; + +SMBIOS_TABLE_TYPE23 gSmbiosType23Template = { + { EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION, sizeof (SMBIOS_TABLE_TYPE23), 0 }, + 0, // Capabilities; + 0, // ResetCount; + 0, // ResetLimit; + 0, // TimerInterval; + 0 // Timeout; +}; + +SMBIOS_TABLE_TYPE32 gSmbiosType32Template = { + { EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION, sizeof (SMBIOS_TABLE_TYPE32), 0 }, + { 0, 0, 0, 0, 0, 0 }, // Reserved[6]; + BootInformationStatusNoError // BootStatus +}; + + + +SMBIOS_TEMPLATE_ENTRY gSmbiosTemplate[] = { + { (SMBIOS_STRUCTURE *)&gSmbiosType0Template, gSmbiosType0Strings }, + { (SMBIOS_STRUCTURE *)&gSmbiosType1Template, gSmbiosType1Strings }, + { (SMBIOS_STRUCTURE *)&gSmbiosType2Template, gSmbiosType2Strings }, + { (SMBIOS_STRUCTURE *)&gSmbiosType3Template, gSmbiosType3Strings }, + { (SMBIOS_STRUCTURE *)&gSmbiosType8Template1, gSmbiosType8Strings1 }, + { (SMBIOS_STRUCTURE *)&gSmbiosType8Template2, gSmbiosType8Strings2 }, + { (SMBIOS_STRUCTURE *)&gSmbiosType8Template3, gSmbiosType8Strings3 }, + { (SMBIOS_STRUCTURE *)&gSmbiosType8Template4, gSmbiosType8Strings4 }, + { (SMBIOS_STRUCTURE *)&gSmbiosType8Template5, gSmbiosType8Strings5 }, + { (SMBIOS_STRUCTURE *)&gSmbiosType8Template6, gSmbiosType8Strings6 }, + { (SMBIOS_STRUCTURE *)&gSmbiosType8Template7, gSmbiosType8Strings7 }, + { (SMBIOS_STRUCTURE *)&gSmbiosType8Template8, gSmbiosType8Strings8 }, + { (SMBIOS_STRUCTURE *)&gSmbiosType8Template9, gSmbiosType8Strings9 }, + { (SMBIOS_STRUCTURE *)&gSmbiosType9Template, gSmbiosType9Strings }, + { (SMBIOS_STRUCTURE *)&gSmbiosType11Template, gSmbiosType11Strings }, + { (SMBIOS_STRUCTURE *)&gSmbiosType12Template, gSmbiosType12Strings }, + { (SMBIOS_STRUCTURE *)&gSmbiosType16Template, NULL }, + { (SMBIOS_STRUCTURE *)&gSmbiosType17Template, gSmbiosType17Strings }, + { (SMBIOS_STRUCTURE *)&gSmbiosType23Template, NULL }, + { (SMBIOS_STRUCTURE *)&gSmbiosType32Template, NULL }, + { NULL, NULL } +}; diff --git a/CdeEmuPkg/EmulatorPkg/Readme.md b/CdeEmuPkg/EmulatorPkg/Readme.md new file mode 100644 index 00000000000..80402086455 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Readme.md @@ -0,0 +1,68 @@ +## Overview + +EmulatorPkg provides an environment where a UEFI environment can be +emulated under an environment where a full UEFI compatible +environment is not possible. (For example, running under an OS +where an OS process hosts the UEFI emulation environment.) + +https://github.com/tianocore/tianocore.github.io/wiki/EmulatorPkg + +## Status + +* Builds and runs under + * a posix-like environment with X windows + - Linux + - OS X + * Windows environment + - Win10 (verified) + - Win8 (not verified) + +## How to Build & Run +**You can use the following command to build.** + * 32bit emulator in Windows: + + `build -p EmulatorPkg\EmulatorPkg.dsc -t VS2017 -a IA32` + + * 64bit emulator in Windows: + + `build -p EmulatorPkg\EmulatorPkg.dsc -t VS2017 -a X64` + + * 32bit emulator in Linux: + + `build -p EmulatorPkg\EmulatorPkg.dsc -t GCC5 -a IA32` + + * 64bit emulator in Linux: + + `build -p EmulatorPkg\EmulatorPkg.dsc -t GCC5 -a X64` + +**You can start/run the emulator using the following command:** + * 32bit emulator in Windows: + + `cd Build\EmulatorIA32\DEBUG_VS2017\IA32\ && WinHost.exe` + + * 64bit emulator in Windows: + + `cd Build\EmulatorX64\DEBUG_VS2017\X64\ && WinHost.exe` + + * 32bit emulator in Linux: + + `cd Build/EmulatorIA32/DEBUG_GCC5/IA32/ && ./Host` + + * 64bit emulator in Linux: + + `cd Build/EmulatorX64/DEBUG_GCC5/X64/ && ./Host` + +**On posix-like environment with the bash shell you can use EmulatorPkg/build.sh to simplify building and running +emulator.** + +For example, to build + run: + +`$ EmulatorPkg/build.sh` +`$ EmulatorPkg/build.sh run` + +The build architecture will match your host machine's architecture. + +On X64 host machines, you can build + run IA32 mode as well: + +`$ EmulatorPkg/build.sh -a IA32` +`$ EmulatorPkg/build.sh -a IA32 run` diff --git a/CdeEmuPkg/EmulatorPkg/RealTimeClockRuntimeDxe/RealTimeClock.c b/CdeEmuPkg/EmulatorPkg/RealTimeClockRuntimeDxe/RealTimeClock.c new file mode 100644 index 00000000000..7b360ddad31 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/RealTimeClockRuntimeDxe/RealTimeClock.c @@ -0,0 +1,299 @@ +/*++ + Emu RTC Architectural Protocol Driver as defined in PI + +Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +BOOLEAN +DayValid ( + IN EFI_TIME *Time + ); + +BOOLEAN +IsLeapYear ( + IN EFI_TIME *Time + ); + +EFI_STATUS +RtcTimeFieldsValid ( + IN EFI_TIME *Time + ); + +EFI_STATUS +EFIAPI +InitializeRealTimeClock ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +EmuGetTime ( + OUT EFI_TIME * Time, + OUT EFI_TIME_CAPABILITIES * Capabilities OPTIONAL + ) +/*++ + +Routine Description: + Service routine for RealTimeClockInstance->GetTime + +Arguments: + + Time - A pointer to storage that will receive a snapshot of the current time. + + Capabilities - A pointer to storage that will receive the capabilities of the real time clock + in the platform. This includes the real time clock's resolution and accuracy. + All reported device capabilities are rounded up. This is an OPTIONAL argument. + +Returns: + + EFI_SUCEESS - The underlying GetSystemTime call occurred and returned + Note that in the NT32 emulation, the GetSystemTime call has no return value + thus you will always receive a EFI_SUCCESS on this. + +**/ +{ + + // + // Check parameter for null pointer + // + if (Time == NULL) { + return EFI_INVALID_PARAMETER; + + } + + gEmuThunk->GetTime (Time, Capabilities); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +EmuSetTime ( + IN EFI_TIME *Time + ) +/*++ + +Routine Description: + Service routine for RealTimeClockInstance->SetTime + +Arguments: + + Time - A pointer to storage containing the time and date information to + program into the real time clock. + +Returns: + + EFI_SUCEESS - The operation completed successfully. + + EFI_INVALID_PARAMETER - One of the fields in Time is out of range. + + EFI_DEVICE_ERROR - The operation could not be complete due to a device error. + +**/ +{ + EFI_STATUS Status; + + if (Time == NULL) { + return EFI_INVALID_PARAMETER; + } + // + // Make sure that the time fields are valid + // + Status = RtcTimeFieldsValid (Time); + if (EFI_ERROR (Status)) { + return Status; + } + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +EmuGetWakeupTime ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ) +/*++ + +Routine Description: + Service routine for RealTimeClockInstance->GetWakeupTime + +Arguments: + This - Indicates the protocol instance structure. + + Enabled - Indicates if the alarm is currently enabled or disabled. + + Pending - Indicates if the alarm signal is pending and requires + acknowledgement. + + Time - The current alarm setting. + +Returns: + + EFI_SUCEESS - The operation completed successfully. + + EFI_DEVICE_ERROR - The operation could not be complete due to a device error. + + EFI_UNSUPPORTED - The operation is not supported on this platform. + +**/ +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +EmuSetWakeupTime ( + IN BOOLEAN Enable, + OUT EFI_TIME *Time + ) +/*++ + +Routine Description: + Service routine for RealTimeClockInstance->SetWakeupTime + +Arguments: + + Enabled - Enable or disable the wakeup alarm. + + Time - If enable is TRUE, the time to set the wakup alarm for. + If enable is FALSE, then this parameter is optional, and + may be NULL. + +Returns: + + EFI_SUCEESS - The operation completed successfully. + + EFI_DEVICE_ERROR - The operation could not be complete due to a device error. + + EFI_INVALID_PARAMETER - A field in Time is out of range. + + EFI_UNSUPPORTED - The operation is not supported on this platform. + +**/ +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +InitializeRealTimeClock ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + Install Real Time Clock Protocol + +Arguments: + ImageHandle - Image Handle + SystemTable - Pointer to system table + +Returns: + + EFI_SUCEESS - Real Time Clock Services are installed into the Runtime Services Table + +**/ +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + SystemTable->RuntimeServices->GetTime = EmuGetTime; + SystemTable->RuntimeServices->SetTime = EmuSetTime; + SystemTable->RuntimeServices->GetWakeupTime = EmuGetWakeupTime; + SystemTable->RuntimeServices->SetWakeupTime = EmuSetWakeupTime; + + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiRealTimeClockArchProtocolGuid, + NULL, + NULL + ); + return Status; +} + +EFI_STATUS +RtcTimeFieldsValid ( + IN EFI_TIME *Time + ) +/*++ + +Routine Description: + + Arguments: + + Returns: +**/ +{ + if (Time->Year < 1998 || + Time->Year > 2099 || + Time->Month < 1 || + Time->Month > 12 || + (!DayValid (Time)) || + Time->Hour > 23 || + Time->Minute > 59 || + Time->Second > 59 || + Time->Nanosecond > 999999999 || + (!(Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE || (Time->TimeZone >= -1440 && Time->TimeZone <= 1440))) || + (Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT))) + ) { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +BOOLEAN +DayValid ( + IN EFI_TIME *Time + ) +{ + + STATIC const INTN DayOfMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + if (Time->Day < 1 || + Time->Day > DayOfMonth[Time->Month - 1] || + (Time->Month == 2 && (!IsLeapYear (Time) && Time->Day > 28)) + ) { + return FALSE; + } + + return TRUE; +} + +BOOLEAN +IsLeapYear ( + IN EFI_TIME *Time + ) +{ + if (Time->Year % 4 == 0) { + if (Time->Year % 100 == 0) { + if (Time->Year % 400 == 0) { + return TRUE; + } else { + return FALSE; + } + } else { + return TRUE; + } + } else { + return FALSE; + } +} diff --git a/CdeEmuPkg/EmulatorPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf b/CdeEmuPkg/EmulatorPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf new file mode 100644 index 00000000000..1ffb4d28f0e --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/RealTimeClockRuntimeDxe/RealTimeClock.inf @@ -0,0 +1,52 @@ +## @file +# Emu Real time clock Architectural Protocol Driver as defined in PI +# +# This real time clock module simulates virtual device by time WinAPI. +# 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 = RealTimeClock + FILE_GUID = f3552032-8985-11db-8429-0040d02b1835 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = InitializeRealTimeClock + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + RealTimeClock.c + + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + EmuThunkLib + UefiDriverEntryPoint + UefiLib + DebugLib + BaseLib + + +[Protocols] + gEfiRealTimeClockArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +[Depex] + TRUE + diff --git a/CdeEmuPkg/EmulatorPkg/ResetRuntimeDxe/Reset.c b/CdeEmuPkg/EmulatorPkg/ResetRuntimeDxe/Reset.c new file mode 100644 index 00000000000..c2b19b3a157 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/ResetRuntimeDxe/Reset.c @@ -0,0 +1,108 @@ +/*++ @file + Reset Architectural Protocol as defined in UEFI/PI under Emulation + +Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + + +VOID +EFIAPI +EmuResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + + // + // Disconnect all + // + Status = gBS->LocateHandleBuffer ( + AllHandles, + NULL, + NULL, + &HandleCount, + &HandleBuffer + ); + if (!EFI_ERROR (Status)) { + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); + } + + gBS->FreePool (HandleBuffer); + } + + + // + // Discard ResetType, always return 0 as exit code + // + gEmuThunk->Exit (0); + + // + // Should never go here + // + ASSERT (FALSE); + + return; +} + + + +EFI_STATUS +EFIAPI +InitializeEmuReset ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + +Arguments: + + ImageHandle of the loaded driver + Pointer to the System Table + +Returns: + + Status +**/ +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + SystemTable->RuntimeServices->ResetSystem = EmuResetSystem; + + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiResetArchProtocolGuid, + NULL, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + diff --git a/CdeEmuPkg/EmulatorPkg/ResetRuntimeDxe/Reset.inf b/CdeEmuPkg/EmulatorPkg/ResetRuntimeDxe/Reset.inf new file mode 100644 index 00000000000..5a790fbcd53 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/ResetRuntimeDxe/Reset.inf @@ -0,0 +1,52 @@ +## @file +# Emu Emulation Reset Architectural Protocol Driver as defined in PI +# +# This Reset module simulates system reset by process exit on 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 = EmuReset + FILE_GUID = 50A18017-37AD-8743-BCF2-DF1A8FF12FAB + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = InitializeEmuReset + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + Reset.c + + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + EmuThunkLib + UefiDriverEntryPoint + UefiLib + DebugLib + BaseLib + + +[Protocols] + gEfiResetArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +[Depex] + TRUE + diff --git a/CdeEmuPkg/EmulatorPkg/Sec/Ia32/SwitchRam.S b/CdeEmuPkg/EmulatorPkg/Sec/Ia32/SwitchRam.S new file mode 100644 index 00000000000..9fe58c7df10 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Sec/Ia32/SwitchRam.S @@ -0,0 +1,89 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2007, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# Module Name: +# +# Stack.asm +# +# Abstract: +# +# Switch the stack from temporary memory to permanent memory. +# +#------------------------------------------------------------------------------ + + .text + + +//------------------------------------------------------------------------------ +// VOID +// EFIAPI +// SecSwitchStack ( +// UINT32 TemporaryMemoryBase, +// UINT32 PermenentMemoryBase +// )// +//------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(SecSwitchStack) +ASM_PFX(SecSwitchStack): +# +# Save three register: eax, ebx, ecx +# + push %eax + push %ebx + push %ecx + push %edx + +# +# !!CAUTION!! this function address's is pushed into stack after +# migration of whole temporary memory, so need save it to permanent +# memory at first! +# + + movl 20(%esp), %ebx # Save the first parameter + movl 24(%esp), %ecx # Save the second parameter + +# +# Save this function's return address into permanent memory at first. +# Then, Fixup the esp point to permanent memory +# + + movl %esp, %eax + subl %ebx, %eax + addl %ecx, %eax + movl (%esp), %edx # copy pushed register's value to permanent memory + movl %edx, (%eax) + movl 4(%esp), %edx + movl %edx, 4(%eax) + movl 8(%esp), %edx + movl %edx, 8(%eax) + movl 12(%esp), %edx + movl %edx, 12(%eax) + movl 16(%esp), %edx + movl %edx, 16(%eax) + movl %eax, %esp # From now, esp is pointed to permanent memory + +# +# Fixup the ebp point to permanent memory +# +#ifndef __APPLE__ + movl %ebp, %eax + subl %ebx, %eax + addl %ecx, %eax + movl %eax, %ebp # From now, ebp is pointed to permanent memory + +# +# Fixup callee's ebp point for PeiDispatch +# + movl (%ebp), %eax + subl %ebx, %eax + addl %ecx, %eax + movl %eax, (%ebp) # From now, Temporary's PPI caller's stack is in permanent memory +#endif + + pop %edx + pop %ecx + pop %ebx + pop %eax + ret + diff --git a/CdeEmuPkg/EmulatorPkg/Sec/Ia32/SwitchRam.asm b/CdeEmuPkg/EmulatorPkg/Sec/Ia32/SwitchRam.asm new file mode 100644 index 00000000000..dcba3c97d82 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Sec/Ia32/SwitchRam.asm @@ -0,0 +1,88 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.
+; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; Stack.asm +; +; Abstract: +; +; Switch the stack from temporary memory to permanent memory. +; +;------------------------------------------------------------------------------ + + .586p + .model flat,C + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; SecSwitchStack ( +; UINT32 TemporaryMemoryBase, +; UINT32 PermenentMemoryBase +; ); +;------------------------------------------------------------------------------ +SecSwitchStack PROC + ; + ; Save three register: eax, ebx, ecx + ; + push eax + push ebx + push ecx + push edx + + ; + ; !!CAUTION!! this function address's is pushed into stack after + ; migration of whole temporary memory, so need save it to permanent + ; memory at first! + ; + + mov ebx, [esp + 20] ; Save the first parameter + mov ecx, [esp + 24] ; Save the second parameter + + ; + ; Save this function's return address into permanent memory at first. + ; Then, Fixup the esp point to permanent memory + ; + mov eax, esp + sub eax, ebx + add eax, ecx + mov edx, dword ptr [esp] ; copy pushed register's value to permanent memory + mov dword ptr [eax], edx + mov edx, dword ptr [esp + 4] + mov dword ptr [eax + 4], edx + mov edx, dword ptr [esp + 8] + mov dword ptr [eax + 8], edx + mov edx, dword ptr [esp + 12] + mov dword ptr [eax + 12], edx + mov edx, dword ptr [esp + 16] ; Update this function's return address into permanent memory + mov dword ptr [eax + 16], edx + mov esp, eax ; From now, esp is pointed to permanent memory + + ; + ; Fixup the ebp point to permanent memory + ; + mov eax, ebp + sub eax, ebx + add eax, ecx + mov ebp, eax ; From now, ebp is pointed to permanent memory + + ; + ; Fixup callee's ebp point for PeiDispatch + ; + mov eax, dword ptr [ebp] + sub eax, ebx + add eax, ecx + mov dword ptr [ebp], eax ; From now, Temporary's PPI caller's stack is in permanent memory + + pop edx + pop ecx + pop ebx + pop eax + ret +SecSwitchStack ENDP + + END diff --git a/CdeEmuPkg/EmulatorPkg/Sec/Ia32/TempRam.c b/CdeEmuPkg/EmulatorPkg/Sec/Ia32/TempRam.c new file mode 100644 index 00000000000..d6621960e21 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Sec/Ia32/TempRam.c @@ -0,0 +1,59 @@ +/*++ @file + Temp RAM PPI + +Copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +#include + +VOID +EFIAPI +SecSwitchStack ( + UINT32 TemporaryMemoryBase, + UINT32 PermenentMemoryBase + ); + + +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ) +{ + // + // Migrate the whole temporary memory to permanent memory. + // + CopyMem ( + (VOID*)(UINTN)PermanentMemoryBase, + (VOID*)(UINTN)TemporaryMemoryBase, + CopySize + ); + + // + // SecSwitchStack function must be invoked after the memory migration + // immediately, also we need fixup the stack change caused by new call into + // permanent memory. + // + SecSwitchStack ((UINT32) TemporaryMemoryBase, (UINT32) PermanentMemoryBase); + + // + // We need *not* fix the return address because currently, + // The PeiCore is executed in flash. + // + + // + // Simulate to invalid temporary memory, terminate temporary memory + // + //ZeroMem ((VOID*)(UINTN)TemporaryMemoryBase, CopySize); + + return EFI_SUCCESS; +} diff --git a/CdeEmuPkg/EmulatorPkg/Sec/Sec.c b/CdeEmuPkg/EmulatorPkg/Sec/Sec.c new file mode 100644 index 00000000000..b5a4bd2e9b1 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Sec/Sec.c @@ -0,0 +1,140 @@ +/*++ @file + Stub SEC that is called from the OS application that is the root of the emulator. + + The OS application will call the SEC with the PEI Entry Point API. + +Copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Sec.h" + + + +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPpi = { + SecTemporaryRamSupport +}; + + +EFI_PEI_PPI_DESCRIPTOR gPrivateDispatchTable[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEfiTemporaryRamSupportPpiGuid, + &mSecTemporaryRamSupportPpi + } +}; + + + +/** + The entry point of PE/COFF Image for the PEI Core, that has been hijacked by this + SEC that sits on top of an OS application. So the entry and exit of this module + has the same API. + + This function is the entry point for the PEI Foundation, which allows the SEC phase + to pass information about the stack, temporary RAM and the Boot Firmware Volume. + In addition, it also allows the SEC phase to pass services and data forward for use + during the PEI phase in the form of one or more PPIs. + There is no limit to the number of additional PPIs that can be passed from SEC into + the PEI Foundation. As part of its initialization phase, the PEI Foundation will add + these SEC-hosted PPIs to its PPI database such that both the PEI Foundation and any + modules can leverage the associated service calls and/or code in these early PPIs. + This function is required to call ProcessModuleEntryPointList() with the Context + parameter set to NULL. ProcessModuleEntryPoint() is never expected to return. + The PEI Core is responsible for calling ProcessLibraryConstructorList() as soon as + the PEI Services Table and the file handle for the PEI Core itself have been established. + If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system. + + @param SecCoreData Points to a data structure containing information about the PEI + core's operating environment, such as the size and location of + temporary RAM, the stack location and the BFV location. + + @param PpiList Points to a list of one or more PPI descriptors to be installed + initially by the PEI core. An empty PPI list consists of a single + descriptor with the end-tag EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST. + As part of its initialization phase, the PEI Foundation will add + these SEC-hosted PPIs to its PPI database such that both the PEI + Foundation and any modules can leverage the associated service calls + and/or code in these early PPIs. + +**/ +VOID +EFIAPI +_ModuleEntryPoint ( + IN EFI_SEC_PEI_HAND_OFF *SecCoreData, + IN EFI_PEI_PPI_DESCRIPTOR *PpiList + ) +{ + EFI_STATUS Status; + EFI_PEI_FV_HANDLE VolumeHandle; + EFI_PEI_FILE_HANDLE FileHandle; + VOID *PeCoffImage; + EFI_PEI_CORE_ENTRY_POINT EntryPoint; + EFI_PEI_PPI_DESCRIPTOR *Ppi; + EFI_PEI_PPI_DESCRIPTOR *SecPpiList; + UINTN SecReseveredMemorySize; + UINTN Index; + EFI_PEI_PPI_DESCRIPTOR PpiArray[10]; + + EMU_MAGIC_PAGE()->PpiList = PpiList; + ProcessLibraryConstructorList (); + + DEBUG ((EFI_D_ERROR, "SEC Has Started\n")); + + // + // Add Our PPIs to the list + // + SecReseveredMemorySize = sizeof (gPrivateDispatchTable); + for (Ppi = PpiList, Index = 1; ; Ppi++, Index++) { + SecReseveredMemorySize += sizeof (EFI_PEI_PPI_DESCRIPTOR); + + if ((Ppi->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) { + // Since we are appending, need to clear out previous list terminator. + Ppi->Flags &= ~EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + break; + } + } + + // Keep everything on a good alignment + SecReseveredMemorySize = ALIGN_VALUE (SecReseveredMemorySize, CPU_STACK_ALIGNMENT); + +#if 0 + // Tell the PEI Core to not use our buffer in temp RAM + SecPpiList = (EFI_PEI_PPI_DESCRIPTOR *)SecCoreData->PeiTemporaryRamBase; + SecCoreData->PeiTemporaryRamBase = (VOID *)((UINTN)SecCoreData->PeiTemporaryRamBase + SecReseveredMemorySize); + SecCoreData->PeiTemporaryRamSize -= SecReseveredMemorySize; +#else + // + // When I subtrack from SecCoreData->PeiTemporaryRamBase PEI Core crashes? Either there is a bug + // or I don't understand temp RAM correctly? + // + + SecPpiList = &PpiArray[0]; + ASSERT (sizeof (PpiArray) >= SecReseveredMemorySize); +#endif + // Copy existing list, and append our entries. + CopyMem (SecPpiList, PpiList, sizeof (EFI_PEI_PPI_DESCRIPTOR) * Index); + CopyMem (&SecPpiList[Index], gPrivateDispatchTable, sizeof (gPrivateDispatchTable)); + + // Find PEI Core and transfer control + VolumeHandle = (EFI_PEI_FV_HANDLE)(UINTN)SecCoreData->BootFirmwareVolumeBase; + FileHandle = NULL; + Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_PEI_CORE, VolumeHandle, &FileHandle); + ASSERT_EFI_ERROR (Status); + + Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &PeCoffImage); + ASSERT_EFI_ERROR (Status); + + Status = PeCoffLoaderGetEntryPoint (PeCoffImage, (VOID **)&EntryPoint); + ASSERT_EFI_ERROR (Status); + + // Transfer control to PEI Core + EntryPoint (SecCoreData, SecPpiList); + + // PEI Core never returns + ASSERT (FALSE); + return; +} + + diff --git a/CdeEmuPkg/EmulatorPkg/Sec/Sec.h b/CdeEmuPkg/EmulatorPkg/Sec/Sec.h new file mode 100644 index 00000000000..7a1ddacd868 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Sec/Sec.h @@ -0,0 +1,45 @@ +/*++ @file + Stub SEC that is called from the OS application that is the root of the emulator. + + The OS application will call the SEC with the PEI Entry Point API. + +Copyright (c) 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SEC_H___ +#define __SEC_H___ + + +#include +#include +#include +#include +#include +#include + +#include + + +// +// I think this should be defined in a MdePkg include file? +// +VOID +EFIAPI +ProcessLibraryConstructorList ( + VOID + ); + +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + + +#endif + diff --git a/CdeEmuPkg/EmulatorPkg/Sec/Sec.inf b/CdeEmuPkg/EmulatorPkg/Sec/Sec.inf new file mode 100644 index 00000000000..ec5d8f19b10 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Sec/Sec.inf @@ -0,0 +1,48 @@ +## @file +# Entry Point of Emu Emulator +# +# Main executable file of Unix Emulator that loads PEI core after initialization finished. +# Portions copyright (c) 2011, Apple Inc. All rights reserved.
+# Copyright (c) 2012, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = EmuSec + FILE_GUID = BCAF98C9-22B0-3B4F-9CBD-C8A6B4DBCEE9 + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + + +[Sources] + Sec.c + +[Sources.X64] + X64/SwitchRam.asm + X64/SwitchRam.S + +[Sources.IA32] + Ia32/TempRam.c + Ia32/SwitchRam.asm + Ia32/SwitchRam.S + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + DebugLib + PeCoffGetEntryPointLib + PeiServicesLib + PpiListLib + BaseMemoryLib + +[Ppis] + gEfiTemporaryRamSupportPpiGuid + +[Pcd] + gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage diff --git a/CdeEmuPkg/EmulatorPkg/Sec/X64/SwitchRam.S b/CdeEmuPkg/EmulatorPkg/Sec/X64/SwitchRam.S new file mode 100644 index 00000000000..4225a74cd6b --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Sec/X64/SwitchRam.S @@ -0,0 +1,66 @@ +#------------------------------------------------------------------------------ +# +# 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 +# +#------------------------------------------------------------------------------ + + + +// EFI_STATUS +// EFIAPI +// SecTemporaryRamSupport ( +// IN CONST EFI_PEI_SERVICES **PeiServices, // %rcx +// IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, // %rdx +// IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, // %r8 +// IN UINTN CopySize // %r9 +// ) +// +ASM_GLOBAL ASM_PFX(SecTemporaryRamSupport) +ASM_PFX(SecTemporaryRamSupport): + // Adjust callers %rbp to account for stack move + subq %rdx, %rbp // Calc offset of %rbp in Temp Memory + addq %r8, %rbp // add in permanent base to offset + + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rdx // Save TemporaryMemoryBase + pushq %r8 // Save PermanentMemoryBase + pushq %r9 // Save CopySize + + // + // Copy all of temp RAM to permanent memory, including stack + // + // CopyMem (PermanentMemoryBase, TemporaryMemoryBase, CopySize); + // %rcx, %rdx, %r8 + movq %r8, %rcx // Shift arguments + movq %r9, %r8 + subq $0x28, %rsp // Allocate register spill area & 16-byte align stack + call ASM_PFX(CopyMem) + // Temp mem stack now copied to permanent location. %esp still in temp memory + addq $0x28, %rsp + + popq %r9 // CopySize (old stack) + popq %r8 // PermanentMemoryBase (old stack) + popq %rdx // TemporaryMemoryBase (old stack) + + movq %rsp, %rcx // Move to new stack + subq %rdx, %rcx // Calc offset of stack in Temp Memory + addq %r8, %rcx // Calc PermanentMemoryBase address + movq %rcx, %rsp // Update stack + // Stack now points to permanent memory + + // ZeroMem (TemporaryMemoryBase /* rcx */, CopySize /* rdx */); + movq %rdx, %rcx + movq %r9, %rdx + subq $0x28, %rsp // Allocate register spill area & 16-byte align stack + call ASM_PFX(ZeroMem) + addq $0x28, %rsp + + // This data comes off the NEW stack + popq %rbp + ret + + diff --git a/CdeEmuPkg/EmulatorPkg/Sec/X64/SwitchRam.asm b/CdeEmuPkg/EmulatorPkg/Sec/X64/SwitchRam.asm new file mode 100644 index 00000000000..3a724360efb --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Sec/X64/SwitchRam.asm @@ -0,0 +1,70 @@ +;------------------------------------------------------------------------------ +; +; 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 +; +;------------------------------------------------------------------------------ + +EXTERN CopyMem:PROC +EXTERN ZeroMem:PROC + + .code + +;------------------------------------------------------------------------------ +; EFI_STATUS +; EFIAPI +; SecTemporaryRamSupport ( +; IN CONST EFI_PEI_SERVICES **PeiServices, // %rcx +; IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, // %rdx +; IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, // %r8 +; IN UINTN CopySize // %r9 +; ) +;------------------------------------------------------------------------------ +SecTemporaryRamSupport PROC + ; Adjust callers %rbp to account for stack move + sub rbp, rdx ; Calc offset of %rbp in Temp Memory + add rbp, r8 ; add in permanent base to offset + + push rbp ; stack frame is for the debugger + mov rbp, rsp + + push rdx ; Save TemporaryMemoryBase + push r8 ; Save PermanentMemoryBase + push r9 ; Save CopySize + + ; + ; Copy all of temp RAM to permanent memory, including stack + ; + ; CopyMem (PermanentMemoryBase, TemporaryMemoryBase, CopySize); + ; %rcx, %rdx, %r8 + mov rcx, r8 ; Shift arguments + mov r8, r9 + sub rsp, 028h ; Allocate register spill area & 16-byte align stack + call CopyMem + ; Temp mem stack now copied to permanent location. %esp still in temp memory + add rsp, 028h + + pop r9 ; CopySize (old stack) + pop r8 ; PermanentMemoryBase (old stack) + pop rdx ; TemporaryMemoryBase (old stack) + + mov rcx, rsp ; Move to new stack + sub rcx, rdx ; Calc offset of stack in Temp Memory + add rcx, r8 ; Calc PermanentMemoryBase address + mov rsp, rcx ; Update stack + ; Stack now points to permanent memory + + ; ZeroMem (TemporaryMemoryBase /* rcx */, CopySize /* rdx */); + mov rcx, rdx + mov rdx, r9 + sub rsp, 028h ; Allocate register spill area & 16-byte align stack + call ZeroMem + add rsp, 028h + + ; This data comes off the NEW stack + pop rbp + ret +SecTemporaryRamSupport ENDP + + END diff --git a/CdeEmuPkg/EmulatorPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.c b/CdeEmuPkg/EmulatorPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.c new file mode 100644 index 00000000000..5563e867f0b --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.c @@ -0,0 +1,68 @@ +/*++ @file + UEFI/PI PEIM to abstract construction of firmware volume in a Unix environment. + +Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved. +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + + + +EFI_STATUS +EFIAPI +PeiInitialzeThunkPpiToProtocolPei ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +/*++ + +Routine Description: + + Perform a call-back into the SEC simulator to get Unix Stuff + +Arguments: + + PeiServices - General purpose services available to every PEIM. + +Returns: + + None + +**/ +{ + EFI_STATUS Status; + EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; + EMU_THUNK_PPI *Thunk; + VOID *Ptr; + + DEBUG ((EFI_D_ERROR, "Emu Thunk PEIM Loaded\n")); + + Status = PeiServicesLocatePpi ( + &gEmuThunkPpiGuid, // GUID + 0, // INSTANCE + &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR + (VOID **)&Thunk // PPI + ); + ASSERT_EFI_ERROR (Status); + + Ptr = Thunk->Thunk (); + + BuildGuidDataHob ( + &gEmuThunkProtocolGuid, // Guid + &Ptr, // Buffer + sizeof (VOID *) // Sizeof Buffer + ); + return Status; +} diff --git a/CdeEmuPkg/EmulatorPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf b/CdeEmuPkg/EmulatorPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf new file mode 100644 index 00000000000..d6679aae218 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/ThunkPpiToProtocolPei/ThunkPpiToProtocolPei.inf @@ -0,0 +1,50 @@ +## @file +# Stuff driver +# +# Tiano PEIM to abstract construction of firmware volume in a Emu environment. +# 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 = ThunkPpiToProtocolPei + FILE_GUID = C32A66D5-D8B7-2640-B768-082C8F083C37 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + + ENTRY_POINT = PeiInitialzeThunkPpiToProtocolPei + + +[Sources] + ThunkPpiToProtocolPei.c + + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + + +[LibraryClasses] + PeiServicesTablePointerLib + PeiServicesLib + HobLib + PeimEntryPoint + DebugLib + + +[Protocols] + gEmuThunkProtocolGuid # PROTOCOL ALWAYS_CONSUMED + + +[Ppis] + gEmuThunkPpiGuid # PPI ALWAYS_CONSUMED + + +[Depex] + gEmuThunkPpiGuid AND gEfiPeiMemoryDiscoveredPpiGuid + diff --git a/CdeEmuPkg/EmulatorPkg/TimerDxe/Timer.c b/CdeEmuPkg/EmulatorPkg/TimerDxe/Timer.c new file mode 100644 index 00000000000..f5fb05ae11f --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/TimerDxe/Timer.c @@ -0,0 +1,346 @@ +/*++ @file + Emu Emulation Timer Architectural Protocol Driver as defined in DXE CIS + + This Timer module uses an Emu Thread to simulate the timer-tick driven + timer service. In the future, the Thread creation should possibly be + abstracted by the CPU architectural protocol + +Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved. +SPDX-License-Identifier: BSD-2-Clause-Patent + + +**/ + +#include "PiDxe.h" +#include +#include +#include "Timer.h" +#include +#include +#include +#include +#include +#include +#include + +// +// Pointer to the CPU Architectural Protocol instance +// +EFI_CPU_ARCH_PROTOCOL *mCpu; + +// +// The Timer Architectural Protocol that this driver produces +// +EFI_TIMER_ARCH_PROTOCOL mTimer = { + EmuTimerDriverRegisterHandler, + EmuTimerDriverSetTimerPeriod, + EmuTimerDriverGetTimerPeriod, + EmuTimerDriverGenerateSoftInterrupt +}; + +// +// The notification function to call on every timer interrupt +// +EFI_TIMER_NOTIFY mTimerNotifyFunction = NULL; + +// +// The current period of the timer interrupt +// +UINT64 mTimerPeriodMs; + + +VOID +EFIAPI +TimerCallback (UINT64 DeltaMs) +{ + EFI_TPL OriginalTPL; + EFI_TIMER_NOTIFY CallbackFunction; + + + OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); + + if (OriginalTPL < TPL_HIGH_LEVEL) { + CallbackFunction = mTimerNotifyFunction; + + // + // Only invoke the callback function if a Non-NULL handler has been + // registered. Assume all other handlers are legal. + // + if (CallbackFunction != NULL) { + CallbackFunction (MultU64x32 (DeltaMs, 10000)); + } + } + + gBS->RestoreTPL (OriginalTPL); + +} + +EFI_STATUS +EFIAPI +EmuTimerDriverRegisterHandler ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN EFI_TIMER_NOTIFY NotifyFunction + ) +/*++ + +Routine Description: + + This function registers the handler NotifyFunction so it is called every time + the timer interrupt fires. It also passes the amount of time since the last + handler call to the NotifyFunction. If NotifyFunction is NULL, then the + handler is unregistered. If the handler is registered, then EFI_SUCCESS is + returned. If the CPU does not support registering a timer interrupt handler, + then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler + when a handler is already registered, then EFI_ALREADY_STARTED is returned. + If an attempt is made to unregister a handler when a handler is not registered, + then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to + register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR + is returned. + +Arguments: + + This - The EFI_TIMER_ARCH_PROTOCOL instance. + + NotifyFunction - The function to call when a timer interrupt fires. This + function executes at TPL_HIGH_LEVEL. The DXE Core will + register a handler for the timer interrupt, so it can know + how much time has passed. This information is used to + signal timer based events. NULL will unregister the handler. + +Returns: + + EFI_SUCCESS - The timer handler was registered. + + EFI_UNSUPPORTED - The platform does not support timer interrupts. + + EFI_ALREADY_STARTED - NotifyFunction is not NULL, and a handler is already + registered. + + EFI_INVALID_PARAMETER - NotifyFunction is NULL, and a handler was not + previously registered. + + EFI_DEVICE_ERROR - The timer handler could not be registered. + +**/ +{ + // + // Check for invalid parameters + // + if (NotifyFunction == NULL && mTimerNotifyFunction == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (NotifyFunction != NULL && mTimerNotifyFunction != NULL) { + return EFI_ALREADY_STARTED; + } + + if (NotifyFunction == NULL) { + /* Disable timer. */ + gEmuThunk->SetTimer (0, TimerCallback); + } else if (mTimerNotifyFunction == NULL) { + /* Enable Timer. */ + gEmuThunk->SetTimer (mTimerPeriodMs, TimerCallback); + } + mTimerNotifyFunction = NotifyFunction; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +EmuTimerDriverSetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod + ) +/*++ + +Routine Description: + + This function adjusts the period of timer interrupts to the value specified + by TimerPeriod. If the timer period is updated, then the selected timer + period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. + If an error occurs while attempting to update the timer period, then the + timer hardware will be put back in its state prior to this call, and + EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt + is disabled. This is not the same as disabling the CPU's interrupts. + Instead, it must either turn off the timer hardware, or it must adjust the + interrupt controller so that a CPU interrupt is not generated when the timer + interrupt fires. + +Arguments: + + This - The EFI_TIMER_ARCH_PROTOCOL instance. + + TimerPeriod - The rate to program the timer interrupt in 100 nS units. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is + returned. If the timer is programmable, then the timer period + will be rounded up to the nearest timer period that is supported + by the timer hardware. If TimerPeriod is set to 0, then the + timer interrupts will be disabled. + +Returns: + + EFI_SUCCESS - The timer period was changed. + + EFI_UNSUPPORTED - The platform cannot change the period of the timer interrupt. + + EFI_DEVICE_ERROR - The timer period could not be changed due to a device error. + +**/ +{ + + // + // If TimerPeriod is 0, then the timer thread should be canceled + // If the TimerPeriod is valid, then create and/or adjust the period of the timer thread + // + if (TimerPeriod == 0 + || ((TimerPeriod > TIMER_MINIMUM_VALUE) + && (TimerPeriod < TIMER_MAXIMUM_VALUE))) { + mTimerPeriodMs = DivU64x32 (TimerPeriod + 5000, 10000); + + gEmuThunk->SetTimer (mTimerPeriodMs, TimerCallback); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +EmuTimerDriverGetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ) +/*++ + +Routine Description: + + This function retrieves the period of timer interrupts in 100 ns units, + returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod + is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is + returned, then the timer is currently disabled. + +Arguments: + + This - The EFI_TIMER_ARCH_PROTOCOL instance. + + TimerPeriod - A pointer to the timer period to retrieve in 100 ns units. If + 0 is returned, then the timer is currently disabled. + +Returns: + + EFI_SUCCESS - The timer period was returned in TimerPeriod. + + EFI_INVALID_PARAMETER - TimerPeriod is NULL. + +**/ +{ + if (TimerPeriod == NULL) { + return EFI_INVALID_PARAMETER; + } + + *TimerPeriod = MultU64x32 (mTimerPeriodMs, 10000); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +EmuTimerDriverGenerateSoftInterrupt ( + IN EFI_TIMER_ARCH_PROTOCOL *This + ) +/*++ + +Routine Description: + + This function generates a soft timer interrupt. If the platform does not support soft + timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned. + If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler() + service, then a soft timer interrupt will be generated. If the timer interrupt is + enabled when this service is called, then the registered handler will be invoked. The + registered handler should not be able to distinguish a hardware-generated timer + interrupt from a software-generated timer interrupt. + +Arguments: + + This - The EFI_TIMER_ARCH_PROTOCOL instance. + +Returns: + + EFI_SUCCESS - The soft timer interrupt was generated. + + EFI_UNSUPPORTED - The platform does not support the generation of soft timer interrupts. + +**/ +{ + return EFI_UNSUPPORTED; +} + +EFI_STATUS +EFIAPI +EmuTimerDriverInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + +Routine Description: + + Initialize the Timer Architectural Protocol driver + +Arguments: + + ImageHandle - ImageHandle of the loaded driver + + SystemTable - Pointer to the System Table + +Returns: + + EFI_SUCCESS - Timer Architectural Protocol created + + EFI_OUT_OF_RESOURCES - Not enough resources available to initialize driver. + + EFI_DEVICE_ERROR - A device error occurred attempting to initialize the driver. + +**/ +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + // + // Make sure the Timer Architectural Protocol is not already installed in the system + // + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid); + + // + // Get the CPU Architectural Protocol instance + // + Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (void *)&mCpu); + ASSERT_EFI_ERROR (Status); + + // + // Start the timer thread at the default timer period + // + Status = mTimer.SetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Install the Timer Architectural Protocol onto a new handle + // + Handle = NULL; + Status = gBS->InstallProtocolInterface ( + &Handle, + &gEfiTimerArchProtocolGuid, + EFI_NATIVE_INTERFACE, + &mTimer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + + return EFI_SUCCESS; +} diff --git a/CdeEmuPkg/EmulatorPkg/TimerDxe/Timer.h b/CdeEmuPkg/EmulatorPkg/TimerDxe/Timer.h new file mode 100644 index 00000000000..c079efe68e6 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/TimerDxe/Timer.h @@ -0,0 +1,67 @@ +/*++ @file + Emu Emulation Architectural Protocol Driver as defined in UEFI/PI. + This Timer module uses an UNIX Thread to simulate the timer-tick driven + timer service. + +Copyright (c) 2006, Intel Corporation. All rights reserved.
+Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved. +SPDX-License-Identifier: BSD-2-Clause-Patent + + +**/ + +#ifndef _TIMER_H_ +#define _TIMER_H_ + + + + +// +// Legal timer value range in 100 ns units +// +#define TIMER_MINIMUM_VALUE 0 +#define TIMER_MAXIMUM_VALUE (0x100000000ULL - 1) + +// +// Default timer value in 100 ns units (50 ms) +// +#define DEFAULT_TIMER_TICK_DURATION 500000 + +// +// Function Prototypes +// +EFI_STATUS +EFIAPI +EmuTimerDriverInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +EFI_STATUS +EFIAPI +EmuTimerDriverRegisterHandler ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN EFI_TIMER_NOTIFY NotifyFunction + ); + +EFI_STATUS +EFIAPI +EmuTimerDriverSetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod + ); + +EFI_STATUS +EFIAPI +EmuTimerDriverGetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ); + +EFI_STATUS +EFIAPI +EmuTimerDriverGenerateSoftInterrupt ( + IN EFI_TIMER_ARCH_PROTOCOL *This + ); + +#endif diff --git a/CdeEmuPkg/EmulatorPkg/TimerDxe/Timer.inf b/CdeEmuPkg/EmulatorPkg/TimerDxe/Timer.inf new file mode 100644 index 00000000000..4d1ff06380e --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/TimerDxe/Timer.inf @@ -0,0 +1,54 @@ +## @file +# Emu Emulation Timer Architectural Protocol Driver as defined in DXE CIS +# +# 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 = EmuTimer + FILE_GUID = 87E1BB14-4D5C-7C4E-A90E-E1415687D062 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = EmuTimerDriverInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + Timer.c + Timer.h + + +[Packages] + MdePkg/MdePkg.dec + EmulatorPkg/EmulatorPkg.dec + + +[LibraryClasses] + UefiBootServicesTableLib + MemoryAllocationLib + EmuThunkLib + UefiDriverEntryPoint + UefiLib + DebugLib + BaseLib + + +[Protocols] + gEfiCpuArchProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiTimerArchProtocolGuid # PROTOCOL ALWAYS_PRODUCED + + +[Depex] + gEfiCpuArchProtocolGuid + diff --git a/CdeEmuPkg/EmulatorPkg/Unix/.gdbinit b/CdeEmuPkg/EmulatorPkg/Unix/.gdbinit new file mode 100644 index 00000000000..173818c0e72 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/.gdbinit @@ -0,0 +1,8 @@ +set confirm off +set output-radix 16 +b SecGdbScriptBreak +command +silent +source SecMain.gdb +c +end diff --git a/CdeEmuPkg/EmulatorPkg/Unix/GdbRun.sh b/CdeEmuPkg/EmulatorPkg/Unix/GdbRun.sh new file mode 100644 index 00000000000..b050ad5e2c5 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/GdbRun.sh @@ -0,0 +1,73 @@ +## @file +# GDB startup script +# +# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +# +# Gdb will set $_exitcode when the program exits. Pre-init it to an unlikely +# return value. +# +set $_exitcode = 42 + +# +# Gdb will call hook-stop on each break. Check to see if $_exitcode was +# changed from the value we pre-initialized it to. If so, the program +# had exited, so gdb should now quit. +# +define hook-stop + if $_exitcode != 42 + quit + else + source Host.gdb + end +end + +# +# We keep track of the number of symbol files we have loaded via gdb +# scripts in the $SymbolFilesAdded variable +# +set $SymbolFileChangesCount = 0 + +# +# This macro adds a symbols file for gdb +# +# @param $arg0 - Symbol file changes number +# @param $arg1 - Symbol file name +# @param $arg2 - Image address +# +define AddFirmwareSymbolFile + if $SymbolFileChangesCount < $arg0 + add-symbol-file $arg1 $arg2 + set $SymbolFileChangesCount = $arg0 + end +end + +# +# This macro removes a symbols file for gdb +# +# @param $arg0 - Symbol file changes number +# @param $arg1 - Symbol file name +# +define RemoveFirmwareSymbolFile + if $SymbolFileChangesCount < $arg0 + # + # Currently there is not a method to remove a single symbol file + # + set $SymbolFileChangesCount = $arg0 + end +end + +if gInXcode == 1 + # in Xcode the program is already running. Issuing a run command + # will cause a fatal debugger error. The break point script that + # is used to source this script sets gInCode to 1. +else + # + # Start the program running + # + run +end diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/BerkeleyPacketFilter.c b/CdeEmuPkg/EmulatorPkg/Unix/Host/BerkeleyPacketFilter.c new file mode 100644 index 00000000000..b847cfa91cc --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/BerkeleyPacketFilter.c @@ -0,0 +1,1106 @@ +/**@file + Berkeley Packet Filter implementation of the EMU_SNP_PROTOCOL that allows the + emulator to get on real networks. + + Tested on Mac OS X. + +Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved. + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + + +#include "Host.h" + +#ifdef __APPLE__ + + +#include + + +#define EMU_SNP_PRIVATE_SIGNATURE SIGNATURE_32('E', 'M', 's', 'n') +typedef struct { + UINTN Signature; + + EMU_IO_THUNK_PROTOCOL *Thunk; + EMU_SNP_PROTOCOL EmuSnp; + EFI_SIMPLE_NETWORK_MODE *Mode; + + int BpfFd; + char *InterfaceName; + EFI_MAC_ADDRESS MacAddress; + u_int ReadBufferSize; + VOID *ReadBuffer; + + // + // Two walking pointers to manage the multiple packets that can be returned + // in a single read. + // + VOID *CurrentReadPointer; + VOID *EndReadPointer; + + UINT32 ReceivedPackets; + UINT32 DroppedPackets; + +} EMU_SNP_PRIVATE; + +#define EMU_SNP_PRIVATE_DATA_FROM_THIS(a) \ + CR(a, EMU_SNP_PRIVATE, EmuSnp, EMU_SNP_PRIVATE_SIGNATURE) + + +// +// Strange, but there doesn't appear to be any structure for the Ethernet header in edk2... +// + +typedef struct { + UINT8 DstAddr[NET_ETHER_ADDR_LEN]; + UINT8 SrcAddr[NET_ETHER_ADDR_LEN]; + UINT16 Type; +} ETHERNET_HEADER; + +/** + 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. + +**/ +EFI_STATUS +EmuSnpCreateMapping ( + IN EMU_SNP_PROTOCOL *This, + IN EFI_SIMPLE_NETWORK_MODE *Mode + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + Private->Mode = Mode; + + // + // Set the broadcast address. + // + SetMem (&Mode->BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF); + + CopyMem (&Mode->CurrentAddress, &Private->MacAddress, sizeof (EFI_MAC_ADDRESS)); + CopyMem (&Mode->PermanentAddress, &Private->MacAddress, sizeof (EFI_MAC_ADDRESS)); + + // + // Since the fake SNP is based on a real NIC, to avoid conflict with the host NIC + // network stack, we use a different MAC address. + // So just change the last byte of the MAC address for the real NIC. + // + Mode->CurrentAddress.Addr[NET_ETHER_ADDR_LEN - 1]++; + + return EFI_SUCCESS; +} + + +static struct bpf_insn mFilterInstructionTemplate[] = { + // Load 4 bytes from the destination MAC address. + BPF_STMT (BPF_LD + BPF_W + BPF_ABS, OFFSET_OF (ETHERNET_HEADER, DstAddr[0])), + + // Compare to first 4 bytes of fake MAC address. + BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 0x12345678, 0, 3 ), + + // Load remaining 2 bytes from the destination MAC address. + BPF_STMT (BPF_LD + BPF_H + BPF_ABS, OFFSET_OF( ETHERNET_HEADER, DstAddr[4])), + + // Compare to remaining 2 bytes of fake MAC address. + BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 0x9ABC, 5, 0 ), + + // Load 4 bytes from the destination MAC address. + BPF_STMT (BPF_LD + BPF_W + BPF_ABS, OFFSET_OF (ETHERNET_HEADER, DstAddr[0])), + + // Compare to first 4 bytes of broadcast MAC address. + BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 0xFFFFFFFF, 0, 2), + + // Load remaining 2 bytes from the destination MAC address. + BPF_STMT (BPF_LD + BPF_H + BPF_ABS, OFFSET_OF( ETHERNET_HEADER, DstAddr[4])), + + // Compare to remaining 2 bytes of broadcast MAC address. + BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 0xFFFF, 1, 0), + + // Reject packet. + BPF_STMT (BPF_RET + BPF_K, 0), + + // Receive entire packet. + BPF_STMT (BPF_RET + BPF_K, -1) +}; + + +EFI_STATUS +OpenBpfFileDescriptor ( + IN EMU_SNP_PRIVATE *Private, + OUT int *Fd + ) +{ + char BfpDeviceName[256]; + int Index; + + // + // Open a Berkeley Packet Filter device. This must be done as root, so this is probably + // the place which is most likely to fail... + // + for (Index = 0; TRUE; Index++ ) { + snprintf (BfpDeviceName, sizeof (BfpDeviceName), "/dev/bpf%d", Index); + + *Fd = open (BfpDeviceName, O_RDWR, 0); + if ( *Fd >= 0 ) { + return EFI_SUCCESS; + } + + if (errno == EACCES) { + printf ( + "SNP: Permissions on '%s' are incorrect. Fix with 'sudo chmod 666 %s'.\n", + BfpDeviceName, + BfpDeviceName + ); + } + + if (errno != EBUSY) { + break; + } + } + + return EFI_OUT_OF_RESOURCES; +} + + +/** + 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. + +**/ +EFI_STATUS +EmuSnpStart ( + IN EMU_SNP_PROTOCOL *This + ) +{ + EFI_STATUS Status; + EMU_SNP_PRIVATE *Private; + struct ifreq BoundIf; + struct bpf_program BpfProgram; + struct bpf_insn *FilterProgram; + u_int Value; + u_int ReadBufferSize; + UINT16 Temp16; + UINT32 Temp32; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + switch (Private->Mode->State) { + case EfiSimpleNetworkStopped: + break; + + case EfiSimpleNetworkStarted: + case EfiSimpleNetworkInitialized: + return EFI_ALREADY_STARTED; + break; + + default: + return EFI_DEVICE_ERROR; + break; + } + + Status = EFI_SUCCESS; + Private->ReadBuffer = NULL; + if (Private->BpfFd == 0) { + Status = OpenBpfFileDescriptor (Private, &Private->BpfFd); + if (EFI_ERROR (Status)) { + goto DeviceErrorExit; + } + + // + // Get the read buffer size. + // + if (ioctl (Private->BpfFd, BIOCGBLEN, &ReadBufferSize) < 0) { + goto DeviceErrorExit; + } + + // + // Default value from BIOCGBLEN is usually too small, so use a much larger size, if necessary. + // + if (ReadBufferSize < FixedPcdGet32 (PcdNetworkPacketFilterSize)) { + ReadBufferSize = FixedPcdGet32 (PcdNetworkPacketFilterSize); + if (ioctl (Private->BpfFd, BIOCSBLEN, &ReadBufferSize) < 0) { + goto DeviceErrorExit; + } + } + + // + // Associate our interface with this BPF file descriptor. + // + AsciiStrCpyS (BoundIf.ifr_name, sizeof (BoundIf.ifr_name), Private->InterfaceName); + if (ioctl (Private->BpfFd, BIOCSETIF, &BoundIf) < 0) { + goto DeviceErrorExit; + } + + // + // Enable immediate mode. + // + Value = 1; + if (ioctl (Private->BpfFd, BIOCIMMEDIATE, &Value) < 0) { + goto DeviceErrorExit; + } + + // + // Enable non-blocking I/O. + // + if (fcntl (Private->BpfFd, F_GETFL, 0) == -1) { + goto DeviceErrorExit; + } + + Value |= O_NONBLOCK; + + if (fcntl (Private->BpfFd, F_SETFL, Value) == -1) { + goto DeviceErrorExit; + } + + // + // Disable "header complete" flag. This means the supplied source MAC address is + // what goes on the wire. + // + Value = 1; + if (ioctl (Private->BpfFd, BIOCSHDRCMPLT, &Value) < 0) { + goto DeviceErrorExit; + } + + // + // Allocate read buffer. + // + Private->ReadBufferSize = ReadBufferSize; + Private->ReadBuffer = malloc (Private->ReadBufferSize); + if (Private->ReadBuffer == NULL) { + goto ErrorExit; + } + + Private->CurrentReadPointer = Private->EndReadPointer = Private->ReadBuffer; + + // + // Install our packet filter: successful reads should only produce broadcast or unicast + // packets directed to our fake MAC address. + // + FilterProgram = malloc (sizeof (mFilterInstructionTemplate)) ; + if ( FilterProgram == NULL ) { + goto ErrorExit; + } + + CopyMem (FilterProgram, &mFilterInstructionTemplate, sizeof (mFilterInstructionTemplate)); + + // + // Insert out fake MAC address into the filter. The data has to be host endian. + // + CopyMem (&Temp32, &Private->Mode->CurrentAddress.Addr[0], sizeof (UINT32)); + FilterProgram[1].k = NTOHL (Temp32); + CopyMem (&Temp16, &Private->Mode->CurrentAddress.Addr[4], sizeof (UINT16)); + FilterProgram[3].k = NTOHS (Temp16); + + BpfProgram.bf_len = sizeof (mFilterInstructionTemplate) / sizeof (struct bpf_insn); + BpfProgram.bf_insns = FilterProgram; + + if (ioctl (Private->BpfFd, BIOCSETF, &BpfProgram) < 0) { + goto DeviceErrorExit; + } + + free (FilterProgram); + + // + // Enable promiscuous mode. + // + if (ioctl (Private->BpfFd, BIOCPROMISC, 0) < 0) { + goto DeviceErrorExit; + } + + + Private->Mode->State = EfiSimpleNetworkStarted; + } + + return Status; + +DeviceErrorExit: + Status = EFI_DEVICE_ERROR; +ErrorExit: + if (Private->ReadBuffer != NULL) { + free (Private->ReadBuffer); + Private->ReadBuffer = NULL; + } + return Status; +} + + +/** + 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. + +**/ +EFI_STATUS +EmuSnpStop ( + IN EMU_SNP_PROTOCOL *This + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + switch ( Private->Mode->State ) { + case EfiSimpleNetworkStarted: + break; + + case EfiSimpleNetworkStopped: + return EFI_NOT_STARTED; + break; + + default: + return EFI_DEVICE_ERROR; + break; + } + + if (Private->BpfFd != 0) { + close (Private->BpfFd); + Private->BpfFd = 0; + } + + if (Private->ReadBuffer != NULL) { + free (Private->ReadBuffer ); + Private->CurrentReadPointer = Private->EndReadPointer = Private->ReadBuffer = NULL; + } + + Private->Mode->State = EfiSimpleNetworkStopped; + + return EFI_SUCCESS; +} + + +/** + 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. + +**/ +EFI_STATUS +EmuSnpInitialize ( + IN EMU_SNP_PROTOCOL *This, + IN UINTN ExtraRxBufferSize OPTIONAL, + IN UINTN ExtraTxBufferSize OPTIONAL + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + switch ( Private->Mode->State ) { + case EfiSimpleNetworkStarted: + break; + + case EfiSimpleNetworkStopped: + return EFI_NOT_STARTED; + break; + + default: + return EFI_DEVICE_ERROR; + break; + } + + Private->Mode->MCastFilterCount = 0; + Private->Mode->ReceiveFilterSetting = 0; + ZeroMem (Private->Mode->MCastFilter, sizeof (Private->Mode->MCastFilter)); + + Private->Mode->State = EfiSimpleNetworkInitialized; + + return EFI_SUCCESS; +} + + +/** + 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. + +**/ +EFI_STATUS +EmuSnpReset ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + switch ( Private->Mode->State ) { + case EfiSimpleNetworkInitialized: + break; + + case EfiSimpleNetworkStopped: + return EFI_NOT_STARTED; + break; + + default: + return EFI_DEVICE_ERROR; + break; + } + + return EFI_SUCCESS; +} + + +/** + 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. + +**/ +EFI_STATUS +EmuSnpShutdown ( + IN EMU_SNP_PROTOCOL *This + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + switch ( Private->Mode->State ) { + case EfiSimpleNetworkInitialized: + break; + + case EfiSimpleNetworkStopped: + return EFI_NOT_STARTED; + break; + + default: + return EFI_DEVICE_ERROR; + break; + } + + Private->Mode->State = EfiSimpleNetworkStarted; + + Private->Mode->ReceiveFilterSetting = 0; + Private->Mode->MCastFilterCount = 0; + ZeroMem (Private->Mode->MCastFilter, sizeof (Private->Mode->MCastFilter)); + + if (Private->BpfFd != 0) { + close (Private->BpfFd); + Private->BpfFd = 0; + } + + if (Private->ReadBuffer != NULL) { + free (Private->ReadBuffer); + Private->CurrentReadPointer = Private->EndReadPointer = Private->ReadBuffer = NULL; + } + + return EFI_SUCCESS; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpReceiveFilters ( + IN EMU_SNP_PROTOCOL *This, + IN UINT32 Enable, + IN UINT32 Disable, + IN BOOLEAN ResetMCastFilter, + IN UINTN MCastFilterCnt OPTIONAL, + IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + // For now, just succeed... + return EFI_SUCCESS; +} + + +/** + 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. + +**/ +EFI_STATUS +EmuSnpStationAddress ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN Reset, + IN EFI_MAC_ADDRESS *New OPTIONAL + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + + +/** + 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. + +**/ +EFI_STATUS +EmuSnpStatistics ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN Reset, + IN OUT UINTN *StatisticsSize OPTIONAL, + OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + + +/** + 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. + +**/ +EFI_STATUS +EmuSnpMCastIpToMac ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN IPv6, + IN EFI_IP_ADDRESS *IP, + OUT EFI_MAC_ADDRESS *MAC + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + + +/** + 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. + +**/ +EFI_STATUS +EmuSnpNvData ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN ReadWrite, + IN UINTN Offset, + IN UINTN BufferSize, + IN OUT VOID *Buffer + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpGetStatus ( + IN EMU_SNP_PROTOCOL *This, + OUT UINT32 *InterruptStatus OPTIONAL, + OUT VOID **TxBuf OPTIONAL + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + if ( InterruptStatus != NULL ) { + *InterruptStatus = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT; + } + + return EFI_SUCCESS; +} + + +/** + 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. + +**/ +EFI_STATUS +EmuSnpTransmit ( + 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 + ) +{ + EMU_SNP_PRIVATE *Private; + ETHERNET_HEADER *EnetHeader; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + if (Private->Mode->State < EfiSimpleNetworkStarted) { + return EFI_NOT_STARTED; + } + + if ( HeaderSize != 0 ) { + if ((DestAddr == NULL) || (Protocol == NULL) || (HeaderSize != Private->Mode->MediaHeaderSize)) { + return EFI_INVALID_PARAMETER; + } + + if (SrcAddr == NULL) { + SrcAddr = &Private->Mode->CurrentAddress; + } + + EnetHeader = (ETHERNET_HEADER *) Buffer; + + CopyMem (EnetHeader->DstAddr, DestAddr, NET_ETHER_ADDR_LEN); + CopyMem (EnetHeader->SrcAddr, SrcAddr, NET_ETHER_ADDR_LEN); + + EnetHeader->Type = HTONS(*Protocol); + } + + if (write (Private->BpfFd, Buffer, BufferSize) < 0) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpReceive ( + 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 + ) +{ + EMU_SNP_PRIVATE *Private; + struct bpf_hdr *BpfHeader; + struct bpf_stat BpfStats; + ETHERNET_HEADER *EnetHeader; + ssize_t Result; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + if (Private->Mode->State < EfiSimpleNetworkStarted) { + return EFI_NOT_STARTED; + } + + ZeroMem (&BpfStats, sizeof( BpfStats)); + + if (ioctl (Private->BpfFd, BIOCGSTATS, &BpfStats) == 0) { + Private->ReceivedPackets += BpfStats.bs_recv; + if (BpfStats.bs_drop > Private->DroppedPackets) { + printf ( + "SNP: STATS: RCVD = %d DROPPED = %d. Probably need to increase BPF PcdNetworkPacketFilterSize?\n", + BpfStats.bs_recv, + BpfStats.bs_drop - Private->DroppedPackets + ); + Private->DroppedPackets = BpfStats.bs_drop; + } + } + + // + // Do we have any remaining packets from the previous read? + // + if (Private->CurrentReadPointer >= Private->EndReadPointer) { + Result = read (Private->BpfFd, Private->ReadBuffer, Private->ReadBufferSize); + if (Result < 0) { + // EAGAIN means that there's no I/O outstanding against this file descriptor. + return (errno == EAGAIN) ? EFI_NOT_READY : EFI_DEVICE_ERROR; + } + + if (Result == 0) { + return EFI_NOT_READY; + } + + Private->CurrentReadPointer = Private->ReadBuffer; + Private->EndReadPointer = Private->CurrentReadPointer + Result; + } + + BpfHeader = Private->CurrentReadPointer; + EnetHeader = Private->CurrentReadPointer + BpfHeader->bh_hdrlen; + + if (BpfHeader->bh_caplen > *BufferSize) { + *BufferSize = BpfHeader->bh_caplen; + return EFI_BUFFER_TOO_SMALL; + } + + CopyMem (Buffer, EnetHeader, BpfHeader->bh_caplen); + *BufferSize = BpfHeader->bh_caplen; + + if (HeaderSize != NULL) { + *HeaderSize = sizeof (ETHERNET_HEADER); + } + + if (DestAddr != NULL) { + ZeroMem (DestAddr, sizeof (EFI_MAC_ADDRESS)); + CopyMem (DestAddr, EnetHeader->DstAddr, NET_ETHER_ADDR_LEN); + } + + if (SrcAddr != NULL) { + ZeroMem (SrcAddr, sizeof (EFI_MAC_ADDRESS)); + CopyMem (SrcAddr, EnetHeader->SrcAddr, NET_ETHER_ADDR_LEN); + } + + if (Protocol != NULL) { + *Protocol = NTOHS (EnetHeader->Type); + } + + Private->CurrentReadPointer += BPF_WORDALIGN (BpfHeader->bh_hdrlen + BpfHeader->bh_caplen); + return EFI_SUCCESS; +} + + +EMU_SNP_PROTOCOL gEmuSnpProtocol = { + GasketSnpCreateMapping, + GasketSnpStart, + GasketSnpStop, + GasketSnpInitialize, + GasketSnpReset, + GasketSnpShutdown, + GasketSnpReceiveFilters, + GasketSnpStationAddress, + GasketSnpStatistics, + GasketSnpMCastIpToMac, + GasketSnpNvData, + GasketSnpGetStatus, + GasketSnpTransmit, + GasketSnpReceive +}; + +EFI_STATUS +GetInterfaceMacAddr ( + EMU_SNP_PRIVATE *Private + ) +{ + EFI_STATUS Status; + struct ifaddrs *IfAddrs; + struct ifaddrs *If; + struct sockaddr_dl *IfSdl; + + if (getifaddrs (&IfAddrs) != 0) { + return EFI_UNSUPPORTED; + } + + // + // Convert the interface name to ASCII so we can find it. + // + Private->InterfaceName = malloc (StrSize (Private->Thunk->ConfigString)); + if (Private->InterfaceName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + UnicodeStrToAsciiStrS ( + Private->Thunk->ConfigString, + Private->InterfaceName, + StrSize (Private->Thunk->ConfigString) + ); + + Status = EFI_NOT_FOUND; + If = IfAddrs; + while (If != NULL) { + IfSdl = (struct sockaddr_dl *)If->ifa_addr; + + if (IfSdl->sdl_family == AF_LINK) { + if (!AsciiStrCmp( Private->InterfaceName, If->ifa_name)) { + CopyMem (&Private->MacAddress, LLADDR (IfSdl), NET_ETHER_ADDR_LEN); + + Status = EFI_SUCCESS; + break; + } + } + + If = If->ifa_next; + } + +Exit: + freeifaddrs (IfAddrs); + return Status; +} + + +EFI_STATUS +EmuSnpThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + EMU_SNP_PRIVATE *Private; + + if (This->Private != NULL) { + return EFI_ALREADY_STARTED; + } + + if (!CompareGuid (This->Protocol, &gEmuSnpProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + Private = malloc (sizeof (EMU_SNP_PRIVATE)); + if (Private == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + + Private->Signature = EMU_SNP_PRIVATE_SIGNATURE; + Private->Thunk = This; + CopyMem (&Private->EmuSnp, &gEmuSnpProtocol, sizeof (gEmuSnpProtocol)); + GetInterfaceMacAddr (Private); + + This->Interface = &Private->EmuSnp; + This->Private = Private; + return EFI_SUCCESS; +} + + +EFI_STATUS +EmuSnpThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + EMU_SNP_PRIVATE *Private; + + if (!CompareGuid (This->Protocol, &gEmuSnpProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + Private = This->Private; + free (Private); + + return EFI_SUCCESS; +} + + + +EMU_IO_THUNK_PROTOCOL gSnpThunkIo = { + &gEmuSnpProtocolGuid, + NULL, + NULL, + 0, + GasketSnpThunkOpen, + GasketSnpThunkClose, + NULL +}; + +#endif diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/BlockIo.c b/CdeEmuPkg/EmulatorPkg/Unix/Host/BlockIo.c new file mode 100644 index 00000000000..7103fea151a --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/BlockIo.c @@ -0,0 +1,702 @@ +/**@file + +Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Host.h" + +#define EMU_BLOCK_IO_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'M', 'b', 'k') +typedef struct { + UINTN Signature; + + EMU_IO_THUNK_PROTOCOL *Thunk; + + char *Filename; + UINTN ReadMode; + UINTN Mode; + + int fd; + + BOOLEAN RemovableMedia; + BOOLEAN WriteProtected; + + UINT64 NumberOfBlocks; + UINT32 BlockSize; + + EMU_BLOCK_IO_PROTOCOL EmuBlockIo; + EFI_BLOCK_IO_MEDIA *Media; + +} EMU_BLOCK_IO_PRIVATE; + +#define EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS(a) \ + CR(a, EMU_BLOCK_IO_PRIVATE, EmuBlockIo, EMU_BLOCK_IO_PRIVATE_SIGNATURE) + + + +EFI_STATUS +EmuBlockIoReset ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + + +/*++ + +This function extends the capability of SetFilePointer to accept 64 bit parameters + +**/ +EFI_STATUS +SetFilePointer64 ( + IN EMU_BLOCK_IO_PRIVATE *Private, + IN INT64 DistanceToMove, + OUT UINT64 *NewFilePointer, + IN INT32 MoveMethod + ) +{ + EFI_STATUS Status; + off_t res; + off_t offset = DistanceToMove; + + Status = EFI_SUCCESS; + res = lseek (Private->fd, offset, (int)MoveMethod); + if (res == -1) { + Status = EFI_INVALID_PARAMETER; + } + + if (NewFilePointer != NULL) { + *NewFilePointer = res; + } + + return Status; +} + + +EFI_STATUS +EmuBlockIoOpenDevice ( + IN EMU_BLOCK_IO_PRIVATE *Private + ) +{ + EFI_STATUS Status; + UINT64 FileSize; + struct statfs buf; + + + // + // If the device is already opened, close it + // + if (Private->fd >= 0) { + EmuBlockIoReset (&Private->EmuBlockIo, FALSE); + } + + // + // Open the device + // + Private->fd = open (Private->Filename, Private->Mode, 0644); + if (Private->fd < 0) { + printf ("EmuOpenBlock: Could not open %s: %s\n", Private->Filename, strerror(errno)); + Private->Media->MediaPresent = FALSE; + Status = EFI_NO_MEDIA; + goto Done; + } + + if (!Private->Media->MediaPresent) { + // + // BugBug: try to emulate if a CD appears - notify drivers to check it out + // + Private->Media->MediaPresent = TRUE; + } + + // + // get the size of the file + // + Status = SetFilePointer64 (Private, 0, &FileSize, SEEK_END); + if (EFI_ERROR (Status)) { + printf ("EmuOpenBlock: Could not get filesize of %s\n", Private->Filename); + Status = EFI_UNSUPPORTED; + goto Done; + } + + if (FileSize == 0) { + // lseek fails on a real device. ioctl calls are OS specific +#if __APPLE__ + { + UINT32 BlockSize; + + if (ioctl (Private->fd, DKIOCGETBLOCKSIZE, &BlockSize) == 0) { + Private->Media->BlockSize = BlockSize; + } + if (ioctl (Private->fd, DKIOCGETBLOCKCOUNT, &Private->NumberOfBlocks) == 0) { + if ((Private->NumberOfBlocks == 0) && (BlockSize == 0x800)) { + // A DVD is ~ 4.37 GB so make up a number + Private->Media->LastBlock = (0x100000000ULL/0x800) - 1; + } else { + Private->Media->LastBlock = Private->NumberOfBlocks - 1; + } + } + ioctl (Private->fd, DKIOCGETMAXBLOCKCOUNTWRITE, &Private->Media->OptimalTransferLengthGranularity); + } +#else + { + size_t BlockSize; + UINT64 DiskSize; + + if (ioctl (Private->fd, BLKSSZGET, &BlockSize) == 0) { + Private->Media->BlockSize = BlockSize; + } + if (ioctl (Private->fd, BLKGETSIZE64, &DiskSize) == 0) { + Private->NumberOfBlocks = DivU64x32 (DiskSize, (UINT32)BlockSize); + Private->Media->LastBlock = Private->NumberOfBlocks - 1; + } + } +#endif + + } else { + Private->Media->BlockSize = Private->BlockSize; + Private->NumberOfBlocks = DivU64x32 (FileSize, Private->Media->BlockSize); + Private->Media->LastBlock = Private->NumberOfBlocks - 1; + + if (fstatfs (Private->fd, &buf) == 0) { +#if __APPLE__ + Private->Media->OptimalTransferLengthGranularity = buf.f_iosize/buf.f_bsize; +#else + Private->Media->OptimalTransferLengthGranularity = buf.f_bsize/buf.f_bsize; +#endif + } + } + + DEBUG ((EFI_D_INIT, "%HEmuOpenBlock: opened %a%N\n", Private->Filename)); + Status = EFI_SUCCESS; + +Done: + if (EFI_ERROR (Status)) { + if (Private->fd >= 0) { + EmuBlockIoReset (&Private->EmuBlockIo, FALSE); + } + } + + return Status; +} + + +EFI_STATUS +EmuBlockIoCreateMapping ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN EFI_BLOCK_IO_MEDIA *Media + ) +{ + EFI_STATUS Status; + EMU_BLOCK_IO_PRIVATE *Private; + + Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); + + Private->Media = Media; + + Media->MediaId = 0; + Media->RemovableMedia = Private->RemovableMedia; + Media->MediaPresent = TRUE; + Media->LogicalPartition = FALSE; + Media->ReadOnly = Private->WriteProtected; + Media->WriteCaching = FALSE; + Media->IoAlign = 1; + Media->LastBlock = 0; // Filled in by OpenDevice + + // EFI_BLOCK_IO_PROTOCOL_REVISION2 + Media->LowestAlignedLba = 0; + Media->LogicalBlocksPerPhysicalBlock = 0; + + + // EFI_BLOCK_IO_PROTOCOL_REVISION3 + Media->OptimalTransferLengthGranularity = 0; + + Status = EmuBlockIoOpenDevice (Private); + + + return Status; +} + + +EFI_STATUS +EmuBlockIoError ( + IN EMU_BLOCK_IO_PRIVATE *Private + ) +{ + EFI_STATUS Status; + BOOLEAN ReinstallBlockIoFlag; + + + switch (errno) { + + case EAGAIN: + Status = EFI_NO_MEDIA; + Private->Media->ReadOnly = FALSE; + Private->Media->MediaPresent = FALSE; + ReinstallBlockIoFlag = FALSE; + break; + + case EACCES: + Private->Media->ReadOnly = FALSE; + Private->Media->MediaPresent = TRUE; + Private->Media->MediaId += 1; + ReinstallBlockIoFlag = TRUE; + Status = EFI_MEDIA_CHANGED; + break; + + case EROFS: + Private->Media->ReadOnly = TRUE; + ReinstallBlockIoFlag = FALSE; + Status = EFI_WRITE_PROTECTED; + break; + + default: + ReinstallBlockIoFlag = FALSE; + Status = EFI_DEVICE_ERROR; + break; + } + return Status; +} + + +EFI_STATUS +EmuBlockIoReadWriteCommon ( + IN EMU_BLOCK_IO_PRIVATE *Private, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer, + IN CHAR8 *CallerName + ) +{ + EFI_STATUS Status; + UINTN BlockSize; + UINT64 LastBlock; + INT64 DistanceToMove; + UINT64 DistanceMoved; + + if (Private->fd < 0) { + Status = EmuBlockIoOpenDevice (Private); + if (EFI_ERROR (Status)) { + return Status; + } + } + + if (!Private->Media->MediaPresent) { + DEBUG ((EFI_D_INIT, "%s: No Media\n", CallerName)); + return EFI_NO_MEDIA; + } + + if (Private->Media->MediaId != MediaId) { + return EFI_MEDIA_CHANGED; + } + + if ((UINTN) Buffer % Private->Media->IoAlign != 0) { + return EFI_INVALID_PARAMETER; + } + + // + // Verify buffer size + // + BlockSize = Private->Media->BlockSize; + if (BufferSize == 0) { + DEBUG ((EFI_D_INIT, "%s: Zero length read\n", CallerName)); + return EFI_SUCCESS; + } + + if ((BufferSize % BlockSize) != 0) { + DEBUG ((EFI_D_INIT, "%s: Invalid read size\n", CallerName)); + return EFI_BAD_BUFFER_SIZE; + } + + LastBlock = Lba + (BufferSize / BlockSize) - 1; + if (LastBlock > Private->Media->LastBlock) { + DEBUG ((EFI_D_INIT, "ReadBlocks: Attempted to read off end of device\n")); + return EFI_INVALID_PARAMETER; + } + // + // Seek to End of File + // + DistanceToMove = MultU64x32 (Lba, BlockSize); + Status = SetFilePointer64 (Private, DistanceToMove, &DistanceMoved, SEEK_SET); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INIT, "WriteBlocks: SetFilePointer failed\n")); + return EmuBlockIoError (Private); + } + + return EFI_SUCCESS; +} + + +/** + 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 +EmuBlockIoReadBlocks ( + 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 + ) +{ + EFI_STATUS Status; + EMU_BLOCK_IO_PRIVATE *Private; + ssize_t len; + + Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); + + Status = EmuBlockIoReadWriteCommon (Private, MediaId, LBA, BufferSize, Buffer, "UnixReadBlocks"); + if (EFI_ERROR (Status)) { + goto Done; + } + + len = read (Private->fd, Buffer, BufferSize); + if (len != BufferSize) { + DEBUG ((EFI_D_INIT, "ReadBlocks: ReadFile failed.\n")); + Status = EmuBlockIoError (Private); + goto Done; + } + + // + // If we read then media is present. + // + Private->Media->MediaPresent = TRUE; + Status = EFI_SUCCESS; + +Done: + if (Token != NULL) { + if (Token->Event != NULL) { + // Caller is responsible for signaling EFI Event + Token->TransactionStatus = Status; + return EFI_SUCCESS; + } + } + 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_CHANGED The MediaId does not match 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 +EmuBlockIoWriteBlocks ( + 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 + ) +{ + EMU_BLOCK_IO_PRIVATE *Private; + ssize_t len; + EFI_STATUS Status; + + + Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); + + Status = EmuBlockIoReadWriteCommon (Private, MediaId, LBA, BufferSize, Buffer, "UnixWriteBlocks"); + if (EFI_ERROR (Status)) { + goto Done; + } + + len = write (Private->fd, Buffer, BufferSize); + if (len != BufferSize) { + DEBUG ((EFI_D_INIT, "ReadBlocks: WriteFile failed.\n")); + Status = EmuBlockIoError (Private); + goto Done; + } + + // + // If the write succeeded, we are not write protected and media is present. + // + Private->Media->MediaPresent = TRUE; + Private->Media->ReadOnly = FALSE; + Status = EFI_SUCCESS; + +Done: + if (Token != NULL) { + if (Token->Event != NULL) { + // Caller is responsible for signaling EFI Event + Token->TransactionStatus = Status; + return EFI_SUCCESS; + } + } + + 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 writing 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 +EmuBlockIoFlushBlocks ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN OUT EFI_BLOCK_IO2_TOKEN *Token + ) +{ + EMU_BLOCK_IO_PRIVATE *Private; + + Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); + + if (Private->fd >= 0) { + fsync (Private->fd); +#if __APPLE__ + fcntl (Private->fd, F_FULLFSYNC); +#endif + } + + + if (Token != NULL) { + if (Token->Event != NULL) { + // Caller is responsible for signaling EFI Event + Token->TransactionStatus = EFI_SUCCESS; + return EFI_SUCCESS; + } + } + + return EFI_SUCCESS; +} + + +/** + 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 + exhaustive verification 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 +EmuBlockIoReset ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + EMU_BLOCK_IO_PRIVATE *Private; + + Private = EMU_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); + + if (Private->fd >= 0) { + close (Private->fd); + Private->fd = -1; + } + + return EFI_SUCCESS; +} + + +char * +StdDupUnicodeToAscii ( + IN CHAR16 *Str + ) +{ + UINTN Size; + char *Ascii; + char *Ptr; + + Size = StrLen (Str) + 1; + Ascii = malloc (Size); + if (Ascii == NULL) { + return NULL; + } + + for (Ptr = Ascii; *Str != '\0'; Ptr++, Str++) { + *Ptr = *Str; + } + *Ptr = 0; + + return Ascii; +} + + +EMU_BLOCK_IO_PROTOCOL gEmuBlockIoProtocol = { + GasketEmuBlockIoReset, + GasketEmuBlockIoReadBlocks, + GasketEmuBlockIoWriteBlocks, + GasketEmuBlockIoFlushBlocks, + GasketEmuBlockIoCreateMapping +}; + +EFI_STATUS +EmuBlockIoThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + EMU_BLOCK_IO_PRIVATE *Private; + char *Str; + + if (This->Private != NULL) { + return EFI_ALREADY_STARTED; + } + + if (!CompareGuid (This->Protocol, &gEmuBlockIoProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + Private = malloc (sizeof (EMU_BLOCK_IO_PRIVATE)); + if (Private == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + + Private->Signature = EMU_BLOCK_IO_PRIVATE_SIGNATURE; + Private->Thunk = This; + CopyMem (&Private->EmuBlockIo, &gEmuBlockIoProtocol, sizeof (gEmuBlockIoProtocol)); + Private->fd = -1; + Private->BlockSize = 512; + + Private->Filename = StdDupUnicodeToAscii (This->ConfigString); + if (Private->Filename == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Str = strstr (Private->Filename, ":"); + if (Str == NULL) { + Private->RemovableMedia = FALSE; + Private->WriteProtected = FALSE; + } else { + for (*Str++ = '\0'; *Str != 0; Str++) { + if (*Str == 'R' || *Str == 'F') { + Private->RemovableMedia = (BOOLEAN) (*Str == 'R'); + } + if (*Str == 'O' || *Str == 'W') { + Private->WriteProtected = (BOOLEAN) (*Str == 'O'); + } + if (*Str == ':') { + Private->BlockSize = strtol (++Str, NULL, 0); + break; + } + } + } + + Private->Mode = Private->WriteProtected ? O_RDONLY : O_RDWR; + + This->Interface = &Private->EmuBlockIo; + This->Private = Private; + return EFI_SUCCESS; +} + + +EFI_STATUS +EmuBlockIoThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + EMU_BLOCK_IO_PRIVATE *Private; + + if (!CompareGuid (This->Protocol, &gEmuBlockIoProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + Private = This->Private; + + if (This->Private != NULL) { + if (Private->Filename != NULL) { + free (Private->Filename); + } + free (This->Private); + This->Private = NULL; + } + + return EFI_SUCCESS; +} + + + +EMU_IO_THUNK_PROTOCOL gBlockIoThunkIo = { + &gEmuBlockIoProtocolGuid, + NULL, + NULL, + 0, + GasketBlockIoThunkOpen, + GasketBlockIoThunkClose, + NULL +}; + + diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/EmuThunk.c b/CdeEmuPkg/EmulatorPkg/Unix/Host/EmuThunk.c new file mode 100644 index 00000000000..fc59bfac6dd --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/EmuThunk.c @@ -0,0 +1,434 @@ +/*++ @file + Since the SEC is the only program in our emulation we + must use a UEFI/PI mechanism to export APIs to other modules. + This is the role of the EFI_EMU_THUNK_PROTOCOL. + + The mUnixThunkTable exists so that a change to EFI_EMU_THUNK_PROTOCOL + will cause an error in initializing the array if all the member functions + are not added. It looks like adding a element to end and not initializing + it may cause the table to be initialized with the members at the end being + set to zero. This is bad as jumping to zero will crash. + +Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Host.h" + +#ifdef __APPLE__ +#define DebugAssert _Mangle__DebugAssert + +#include +#include +#include +#include + +#undef DebugAssert +#endif + +int settimer_initialized; +struct timeval settimer_timeval; +UINTN settimer_callback = 0; + +BOOLEAN gEmulatorInterruptEnabled = FALSE; + + +UINTN +SecWriteStdErr ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + ssize_t Return; + + Return = write (STDERR_FILENO, (const void *)Buffer, (size_t)NumberOfBytes); + + return (Return == -1) ? 0 : Return; +} + + +EFI_STATUS +SecConfigStdIn ( + VOID + ) +{ + struct termios tty; + + // + // Need to turn off line buffering, ECHO, and make it unbuffered. + // + tcgetattr (STDIN_FILENO, &tty); + tty.c_lflag &= ~(ICANON | ECHO); + tcsetattr (STDIN_FILENO, TCSANOW, &tty); + +// setvbuf (STDIN_FILENO, NULL, _IONBF, 0); + + // now ioctl FIONREAD will do what we need + return EFI_SUCCESS; +} + +UINTN +SecWriteStdOut ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + ssize_t Return; + + Return = write (STDOUT_FILENO, (const void *)Buffer, (size_t)NumberOfBytes); + + return (Return == -1) ? 0 : Return; +} + +UINTN +SecReadStdIn ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + ssize_t Return; + + Return = read (STDIN_FILENO, Buffer, (size_t)NumberOfBytes); + + return (Return == -1) ? 0 : Return; +} + +BOOLEAN +SecPollStdIn ( + VOID + ) +{ + int Result; + int Bytes; + + Result = ioctl (STDIN_FILENO, FIONREAD, &Bytes); + if (Result == -1) { + return FALSE; + } + + return (BOOLEAN)(Bytes > 0); +} + + +VOID * +SecMalloc ( + IN UINTN Size + ) +{ + return malloc ((size_t)Size); +} + +VOID * +SecValloc ( + IN UINTN Size + ) +{ + return valloc ((size_t)Size); +} + +BOOLEAN +SecFree ( + IN VOID *Ptr + ) +{ + if (EfiSystemMemoryRange (Ptr)) { + // If an address range is in the EFI memory map it was alloced via EFI. + // So don't free those ranges and let the caller know. + return FALSE; + } + + free (Ptr); + return TRUE; +} + + +void +settimer_handler (int sig) +{ + struct timeval timeval; + UINT64 delta; + + gettimeofday (&timeval, NULL); + delta = ((UINT64)timeval.tv_sec * 1000) + (timeval.tv_usec / 1000) + - ((UINT64)settimer_timeval.tv_sec * 1000) + - (settimer_timeval.tv_usec / 1000); + settimer_timeval = timeval; + + if (settimer_callback) { + ReverseGasketUint64 (settimer_callback, delta); + } +} + +VOID +SecSetTimer ( + IN UINT64 PeriodMs, + IN EMU_SET_TIMER_CALLBACK CallBack + ) +{ + struct itimerval timerval; + UINT32 remainder; + + if (!settimer_initialized) { + struct sigaction act; + + settimer_initialized = 1; + act.sa_handler = settimer_handler; + act.sa_flags = 0; + sigemptyset (&act.sa_mask); + gEmulatorInterruptEnabled = TRUE; + if (sigaction (SIGALRM, &act, NULL) != 0) { + printf ("SetTimer: sigaction error %s\n", strerror (errno)); + } + if (gettimeofday (&settimer_timeval, NULL) != 0) { + printf ("SetTimer: gettimeofday error %s\n", strerror (errno)); + } + } + timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000); + DivU64x32Remainder(PeriodMs, 1000, &remainder); + timerval.it_value.tv_usec = remainder * 1000; + timerval.it_value.tv_sec = DivU64x32(PeriodMs, 1000); + timerval.it_interval = timerval.it_value; + + if (setitimer (ITIMER_REAL, &timerval, NULL) != 0) { + printf ("SetTimer: setitimer error %s\n", strerror (errno)); + } + settimer_callback = (UINTN)CallBack; +} + + +VOID +SecEnableInterrupt ( + VOID + ) +{ + sigset_t sigset; + + gEmulatorInterruptEnabled = TRUE; + // Since SetTimer() uses SIGALRM we emulate turning on and off interrupts + // by enabling/disabling SIGALRM. + sigemptyset (&sigset); + sigaddset (&sigset, SIGALRM); + pthread_sigmask (SIG_UNBLOCK, &sigset, NULL); +} + + +VOID +SecDisableInterrupt ( + VOID + ) +{ + sigset_t sigset; + + // Since SetTimer() uses SIGALRM we emulate turning on and off interrupts + // by enabling/disabling SIGALRM. + sigemptyset (&sigset); + sigaddset (&sigset, SIGALRM); + pthread_sigmask (SIG_BLOCK, &sigset, NULL); + gEmulatorInterruptEnabled = FALSE; +} + + +BOOLEAN +SecInterruptEanbled (void) +{ + return gEmulatorInterruptEnabled; +} + + +UINT64 +QueryPerformanceFrequency ( + VOID + ) +{ + // Hard code to nanoseconds + return 1000000000ULL; +} + +UINT64 +QueryPerformanceCounter ( + VOID + ) +{ +#if __APPLE__ + UINT64 Start; + static mach_timebase_info_data_t sTimebaseInfo; + + + Start = mach_absolute_time (); + + // Convert to nanoseconds. + + // If this is the first time we've run, get the timebase. + // We can use denom == 0 to indicate that sTimebaseInfo is + // uninitialised because it makes no sense to have a zero + // denominator is a fraction. + + if ( sTimebaseInfo.denom == 0 ) { + (void) mach_timebase_info(&sTimebaseInfo); + } + + // Do the maths. We hope that the multiplication doesn't + // overflow; the price you pay for working in fixed point. + + return (Start * sTimebaseInfo.numer) / sTimebaseInfo.denom; +#else + // Need to figure out what to do for Linux? + return 0; +#endif +} + + + +VOID +SecSleep ( + IN UINT64 Nanoseconds + ) +{ + struct timespec rq, rm; + struct timeval start, end; + unsigned long MicroSec; + + rq.tv_sec = DivU64x32 (Nanoseconds, 1000000000); + rq.tv_nsec = ModU64x32 (Nanoseconds, 1000000000); + + // + // nanosleep gets interrupted by our timer tic. + // we need to track wall clock time or we will stall for way too long + // + gettimeofday (&start, NULL); + end.tv_sec = start.tv_sec + rq.tv_sec; + MicroSec = (start.tv_usec + rq.tv_nsec/1000); + end.tv_usec = MicroSec % 1000000; + if (MicroSec > 1000000) { + end.tv_sec++; + } + + while (nanosleep (&rq, &rm) == -1) { + if (errno != EINTR) { + break; + } + gettimeofday (&start, NULL); + if (start.tv_sec > end.tv_sec) { + break; + } if ((start.tv_sec == end.tv_sec) && (start.tv_usec > end.tv_usec)) { + break; + } + rq = rm; + } +} + + +VOID +SecCpuSleep ( + VOID + ) +{ + struct timespec rq, rm; + + // nanosleep gets interrupted by the timer tic + rq.tv_sec = 1; + rq.tv_nsec = 0; + + nanosleep (&rq, &rm); +} + + +VOID +SecExit ( + UINTN Status + ) +{ + exit (Status); +} + + +VOID +SecGetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ) +{ + struct tm *tm; + time_t t; + + t = time (NULL); + tm = localtime (&t); + + Time->Year = 1900 + tm->tm_year; + Time->Month = tm->tm_mon + 1; + Time->Day = tm->tm_mday; + Time->Hour = tm->tm_hour; + Time->Minute = tm->tm_min; + Time->Second = tm->tm_sec; + Time->Nanosecond = 0; + Time->TimeZone = timezone / 60; + Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0) + | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0); + + if (Capabilities != NULL) { + Capabilities->Resolution = 1; + Capabilities->Accuracy = 50000000; + Capabilities->SetsToZero = FALSE; + } +} + + + +VOID +SecSetTime ( + IN EFI_TIME *Time + ) +{ + // Don't change the time on the system + // We could save delta to localtime() and have SecGetTime adjust return values? + return; +} + + +EFI_STATUS +SecGetNextProtocol ( + IN BOOLEAN EmuBusDriver, + OUT EMU_IO_THUNK_PROTOCOL **Instance OPTIONAL + ) +{ + return GetNextThunkProtocol (EmuBusDriver, Instance); +} + + +EMU_THUNK_PROTOCOL gEmuThunkProtocol = { + GasketSecWriteStdErr, + GasketSecConfigStdIn, + GasketSecWriteStdOut, + GasketSecReadStdIn, + GasketSecPollStdIn, + GasketSecMalloc, + GasketSecValloc, + GasketSecFree, + GasketSecPeCoffGetEntryPoint, + GasketSecPeCoffRelocateImageExtraAction, + GasketSecPeCoffUnloadImageExtraAction, + GasketSecEnableInterrupt, + GasketSecDisableInterrupt, + GasketQueryPerformanceFrequency, + GasketQueryPerformanceCounter, + GasketSecSleep, + GasketSecCpuSleep, + GasketSecExit, + GasketSecGetTime, + GasketSecSetTime, + GasketSecSetTimer, + GasketSecGetNextProtocol +}; + + +VOID +SecInitThunkProtocol ( + VOID + ) +{ + // timezone and daylight lib globals depend on tzset be called 1st. + tzset (); +} + diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/Gasket.h b/CdeEmuPkg/EmulatorPkg/Unix/Host/Gasket.h new file mode 100644 index 00000000000..c1e0debe842 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/Gasket.h @@ -0,0 +1,645 @@ +/** @file + + Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+ Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _GASKET_H_ +#define _GASKET_H_ + +// +// EMU_THUNK_PROTOCOL gaskets (EFIAPI to UNIX ABI) +// + +UINTN +EFIAPI +GasketSecWriteStdErr ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ); + +EFI_STATUS +EFIAPI +GasketSecConfigStdIn ( + VOID + ); + +UINTN +EFIAPI +GasketSecWriteStdOut ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ); + +UINTN +EFIAPI +GasketSecReadStdIn ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ); + +BOOLEAN +EFIAPI +GasketSecPollStdIn ( + VOID + ); + +VOID * +EFIAPI +GasketSecMalloc ( + IN UINTN Size + ); + +VOID * +EFIAPI +GasketSecValloc ( + IN UINTN Size + ); + +BOOLEAN +EFIAPI +GasketSecFree ( + IN VOID *Ptr + ); + + +RETURN_STATUS +EFIAPI +GasketSecPeCoffGetEntryPoint ( + IN VOID *Pe32Data, + IN OUT VOID **EntryPoint + ); + +VOID +EFIAPI +GasketSecPeCoffRelocateImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + +VOID +EFIAPI +GasketSecPeCoffUnloadImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + +VOID +EFIAPI +GasketSecSetTimer ( + IN UINT64 PeriodMs, + IN EMU_SET_TIMER_CALLBACK CallBack + ); + +VOID +EFIAPI +GasketSecEnableInterrupt ( + VOID + ); + +VOID +EFIAPI +GasketSecDisableInterrupt ( + VOID + ); + +UINT64 +EFIAPI +GasketQueryPerformanceFrequency ( + VOID + ); + +UINT64 +EFIAPI +GasketQueryPerformanceCounter ( + VOID + ); + + +VOID +EFIAPI +GasketSecSleep ( + IN UINT64 Nanoseconds + ); + +VOID +EFIAPI +GasketSecCpuSleep ( + VOID + ); + +VOID +EFIAPI +GasketSecExit ( + UINTN Status + ); + +VOID +EFIAPI +GasketSecGetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ); + +VOID +EFIAPI +GasketSecSetTime ( + IN EFI_TIME *Time + ); + +EFI_STATUS +EFIAPI +GasketSecGetNextProtocol ( + IN BOOLEAN EmuBusDriver, + OUT EMU_IO_THUNK_PROTOCOL **Instance OPTIONAL + ); + + +// PPIs produced by SEC + + +EFI_STATUS +EFIAPI +GasketSecUnixPeiAutoScan ( + IN UINTN Index, + OUT EFI_PHYSICAL_ADDRESS *MemoryBase, + OUT UINT64 *MemorySize + ); + +VOID * +EFIAPI +GasketSecEmuThunkAddress ( + VOID + ); + + +EFI_STATUS +EFIAPI +GasketSecUnixUnixFwhAddress ( + IN OUT UINT64 *FwhSize, + IN OUT EFI_PHYSICAL_ADDRESS *FwhBase + ); + + + +// +// Reverse (UNIX to EFIAPI) gaskets +// + +typedef +void +(EFIAPI *CALL_BACK) ( + UINT64 Delta + ); + +UINTN +ReverseGasketUint64 ( + UINTN CallBack, + UINT64 a + ); + +UINTN +ReverseGasketUint64Uint64 ( + VOID *CallBack, + VOID *Context, + VOID *Key + ); + +// +// Gasket functions for EFI_EMU_UGA_IO_PROTOCOL +// + + +EFI_STATUS +EFIAPI +GasketX11Size ( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo, + UINT32 Width, + UINT32 Height + ); + +EFI_STATUS +EFIAPI +GasketX11CheckKey ( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo + ); + +EFI_STATUS +EFIAPI +GasketX11GetKey ( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo, + EFI_KEY_DATA *key + ); + +EFI_STATUS +EFIAPI +GasketX11KeySetState ( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo, + EFI_KEY_TOGGLE_STATE *KeyToggleState + ); + +EFI_STATUS +EFIAPI +GasketX11RegisterKeyNotify ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeCallBack, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakCallBack, + IN VOID *Context + ); + + +EFI_STATUS +EFIAPI +GasketX11Blt ( + 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 + ); + +EFI_STATUS +EFIAPI +GasketX11CheckPointer ( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo + ); + +EFI_STATUS +EFIAPI +GasketX11GetPointerState ( + EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsWindowsIo, + EFI_SIMPLE_POINTER_STATE *state + ); + +EFI_STATUS +EFIAPI +GasketX11GraphicsWindowOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketX11GraphicsWindowClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +// Pthreads + +UINTN +EFIAPI +GasketPthreadMutexLock ( + IN VOID *Mutex + ); + + + +UINTN +EFIAPI +GasketPthreadMutexUnLock ( + IN VOID *Mutex + ); + + +UINTN +EFIAPI +GasketPthreadMutexTryLock ( + IN VOID *Mutex + ); + + +VOID * +EFIAPI +GasketPthreadMutexInit ( + IN VOID + ); + + +UINTN +EFIAPI +GasketPthreadMutexDestroy ( + IN VOID *Mutex + ); + + +UINTN +EFIAPI +GasketPthreadCreate ( + IN VOID *Thread, + IN VOID *Attribute, + IN THREAD_THUNK_THREAD_ENTRY Start, + IN VOID *Context + ); + +VOID +EFIAPI +GasketPthreadExit ( + IN VOID *ValuePtr + ); + + +UINTN +EFIAPI +GasketPthreadSelf ( + VOID + ); + +EFI_STATUS +EFIAPI +GasketPthreadOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketPthreadClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + + +// PosixFileSystem + +EFI_STATUS +EFIAPI +GasketPosixOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ); + +EFI_STATUS +EFIAPI +GasketPosixFileOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +EFI_STATUS +EFIAPI +GasketPosixFileCLose ( + IN EFI_FILE_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketPosixFileDelete ( + IN EFI_FILE_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketPosixFileRead ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +EFI_STATUS +EFIAPI +GasketPosixFileWrite ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +EFI_STATUS +EFIAPI +GasketPosixFileSetPossition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ); + +EFI_STATUS +EFIAPI +GasketPosixFileGetPossition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ); + +EFI_STATUS +EFIAPI +GasketPosixFileGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +EFI_STATUS +EFIAPI +GasketPosixFileSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +EFI_STATUS +EFIAPI +GasketPosixFileFlush ( + IN EFI_FILE_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketPosixFileSystmeThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketPosixFileSystmeThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketEmuBlockIoReset ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +EFI_STATUS +EFIAPI +GasketEmuBlockIoReadBlocks ( + 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 + ); + +EFI_STATUS +EFIAPI +GasketEmuBlockIoWriteBlocks ( + 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 + ); + +EFI_STATUS +EFIAPI +GasketEmuBlockIoFlushBlocks ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN OUT EFI_BLOCK_IO2_TOKEN *Token + ); + +EFI_STATUS +EFIAPI +GasketEmuBlockIoCreateMapping ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN EFI_BLOCK_IO_MEDIA *Media + ); + +EFI_STATUS +EFIAPI +GasketBlockIoThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketBlockIoThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketSnpThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketSnpThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketSnpCreateMapping ( + IN EMU_SNP_PROTOCOL *This, + IN EFI_SIMPLE_NETWORK_MODE *Media + ); + +EFI_STATUS +EFIAPI +GasketSnpStart ( + IN EMU_SNP_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketSnpStop ( + IN EMU_SNP_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketSnpInitialize ( + IN EMU_SNP_PROTOCOL *This, + IN UINTN ExtraRxBufferSize OPTIONAL, + IN UINTN ExtraTxBufferSize OPTIONAL + ); + +EFI_STATUS +EFIAPI +GasketSnpReset ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + +EFI_STATUS +EFIAPI +GasketSnpShutdown ( + IN EMU_SNP_PROTOCOL *This + ); + +EFI_STATUS +EFIAPI +GasketSnpReceiveFilters ( + IN EMU_SNP_PROTOCOL *This, + IN UINT32 Enable, + IN UINT32 Disable, + IN BOOLEAN ResetMCastFilter, + IN UINTN MCastFilterCnt OPTIONAL, + IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL + ); + +EFI_STATUS +EFIAPI +GasketSnpStationAddress ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN Reset, + IN EFI_MAC_ADDRESS *New OPTIONAL + ); + +EFI_STATUS +EFIAPI +GasketSnpStatistics ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN Reset, + IN OUT UINTN *StatisticsSize OPTIONAL, + OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL + ); + +EFI_STATUS +EFIAPI +GasketSnpMCastIpToMac ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN IPv6, + IN EFI_IP_ADDRESS *IP, + OUT EFI_MAC_ADDRESS *MAC + ); + +EFI_STATUS +EFIAPI +GasketSnpNvData ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN ReadWrite, + IN UINTN Offset, + IN UINTN BufferSize, + IN OUT VOID *Buffer + ); + +EFI_STATUS +EFIAPI +GasketSnpGetStatus ( + IN EMU_SNP_PROTOCOL *This, + OUT UINT32 *InterruptStatus OPTIONAL, + OUT VOID **TxBuf OPTIONAL + ); + +EFI_STATUS +EFIAPI +GasketSnpTransmit ( + 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 + ); + +EFI_STATUS +EFIAPI +GasketSnpReceive ( + 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 + ); + + +#endif + + diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/Host.c b/CdeEmuPkg/EmulatorPkg/Unix/Host/Host.c new file mode 100644 index 00000000000..3a0e58bc6c6 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/Host.c @@ -0,0 +1,1283 @@ +/*++ @file + +Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Host.h" + +#ifdef __APPLE__ +#define MAP_ANONYMOUS MAP_ANON +#endif + + +// +// Globals +// + +EMU_THUNK_PPI mSecEmuThunkPpi = { + GasketSecUnixPeiAutoScan, + GasketSecUnixFdAddress, + GasketSecEmuThunkAddress +}; + +char *gGdbWorkingFileName = NULL; +unsigned int mScriptSymbolChangesCount = 0; + + +// +// Default information about where the FD is located. +// This array gets filled in with information from EFI_FIRMWARE_VOLUMES +// EFI_FIRMWARE_VOLUMES is a host environment variable set by system.cmd. +// The number of array elements is allocated base on parsing +// EFI_FIRMWARE_VOLUMES and the memory is never freed. +// +UINTN gFdInfoCount = 0; +EMU_FD_INFO *gFdInfo; + +// +// Array that supports separate memory ranges. +// The memory ranges are set in system.cmd via the EFI_MEMORY_SIZE variable. +// The number of array elements is allocated base on parsing +// EFI_MEMORY_SIZE and the memory is never freed. +// +UINTN gSystemMemoryCount = 0; +EMU_SYSTEM_MEMORY *gSystemMemory; + + + +UINTN mImageContextModHandleArraySize = 0; +IMAGE_CONTEXT_TO_MOD_HANDLE *mImageContextModHandleArray = NULL; + +EFI_PEI_PPI_DESCRIPTOR *gPpiList; + + +int gInXcode = 0; + + +/*++ + Breakpoint target for Xcode project. Set in the Xcode XML + + Xcode breakpoint will 'source Host.gdb' + gGdbWorkingFileName is set to Host.gdb + +**/ +VOID +SecGdbConfigBreak ( + VOID + ) +{ +} + + + +/*++ + +Routine Description: + Main entry point to SEC for Unix. This is a unix program + +Arguments: + Argc - Number of command line arguments + Argv - Array of command line argument strings + Envp - Array of environment variable strings + +Returns: + 0 - Normal exit + 1 - Abnormal exit + +**/ +int +main ( + IN int Argc, + IN char **Argv, + IN char **Envp + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS InitialStackMemory; + UINT64 InitialStackMemorySize; + UINTN Index; + UINTN Index1; + UINTN Index2; + UINTN PeiIndex; + CHAR8 *FileName; + BOOLEAN Done; + EFI_PEI_FILE_HANDLE FileHandle; + VOID *SecFile; + CHAR16 *MemorySizeStr; + CHAR16 *FirmwareVolumesStr; + UINTN *StackPointer; + FILE *GdbTempFile; + + // + // Xcode does not support sourcing gdb scripts directly, so the Xcode XML + // has a break point script to source the GdbRun.sh script. + // + SecGdbConfigBreak (); + + // + // If dlopen doesn't work, then we build a gdb script to allow the + // symbols to be loaded. + // + Index = strlen (*Argv); + gGdbWorkingFileName = AllocatePool (Index + strlen(".gdb") + 1); + strcpy (gGdbWorkingFileName, *Argv); + strcat (gGdbWorkingFileName, ".gdb"); + + // + // Empty out the gdb symbols script file. + // + GdbTempFile = fopen (gGdbWorkingFileName, "w"); + if (GdbTempFile != NULL) { + fclose (GdbTempFile); + } + + printf ("\nEDK II UNIX Host Emulation Environment from http://www.tianocore.org/edk2/\n"); + + setbuf (stdout, 0); + setbuf (stderr, 0); + + MemorySizeStr = (CHAR16 *) PcdGetPtr (PcdEmuMemorySize); + FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdEmuFirmwareVolume); + + // + // PPIs pased into PEI_CORE + // + AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI, &gEmuThunkPpiGuid, &mSecEmuThunkPpi); + + SecInitThunkProtocol (); + + // + // Emulator Bus Driver Thunks + // + AddThunkProtocol (&gX11ThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuGop), TRUE); + AddThunkProtocol (&gPosixFileSystemThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuFileSystem), TRUE); + AddThunkProtocol (&gBlockIoThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuVirtualDisk), TRUE); + AddThunkProtocol (&gSnpThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuNetworkInterface), TRUE); + + // + // Emulator other Thunks + // + AddThunkProtocol (&gPthreadThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuApCount), FALSE); + + // EmuSecLibConstructor (); + + gPpiList = GetThunkPpiList (); + + // + // Allocate space for gSystemMemory Array + // + gSystemMemoryCount = CountSeparatorsInString (MemorySizeStr, '!') + 1; + gSystemMemory = AllocateZeroPool (gSystemMemoryCount * sizeof (EMU_SYSTEM_MEMORY)); + if (gSystemMemory == NULL) { + printf ("ERROR : Can not allocate memory for system. Exiting.\n"); + exit (1); + } + // + // Allocate space for gSystemMemory Array + // + gFdInfoCount = CountSeparatorsInString (FirmwareVolumesStr, '!') + 1; + gFdInfo = AllocateZeroPool (gFdInfoCount * sizeof (EMU_FD_INFO)); + if (gFdInfo == NULL) { + printf ("ERROR : Can not allocate memory for fd info. Exiting.\n"); + exit (1); + } + + printf (" BootMode 0x%02x\n", (unsigned int)PcdGet32 (PcdEmuBootMode)); + + // + // Open up a 128K file to emulate temp memory for SEC. + // on a real platform this would be SRAM, or using the cache as RAM. + // Set InitialStackMemory to zero so UnixOpenFile will allocate a new mapping + // + InitialStackMemorySize = STACK_SIZE; + InitialStackMemory = (UINTN)MapMemory ( + 0, (UINT32) InitialStackMemorySize, + PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE + ); + if (InitialStackMemory == 0) { + printf ("ERROR : Can not open SecStack Exiting\n"); + exit (1); + } + + printf (" OS Emulator passing in %u KB of temp RAM at 0x%08lx to SEC\n", + (unsigned int)(InitialStackMemorySize / 1024), + (unsigned long)InitialStackMemory + ); + + for (StackPointer = (UINTN*) (UINTN) InitialStackMemory; + StackPointer < (UINTN*)(UINTN)((UINTN) InitialStackMemory + (UINT64) InitialStackMemorySize); + StackPointer ++) { + *StackPointer = 0x5AA55AA5; + } + + // + // Open All the firmware volumes and remember the info in the gFdInfo global + // + FileName = (CHAR8 *) AllocatePool (StrLen (FirmwareVolumesStr) + 1); + if (FileName == NULL) { + printf ("ERROR : Can not allocate memory for firmware volume string\n"); + exit (1); + } + + Index2 = 0; + for (Done = FALSE, Index = 0, PeiIndex = 0, SecFile = NULL; + FirmwareVolumesStr[Index2] != 0; + Index++) { + for (Index1 = 0; (FirmwareVolumesStr[Index2] != '!') && (FirmwareVolumesStr[Index2] != 0); Index2++) { + FileName[Index1++] = FirmwareVolumesStr[Index2]; + } + if (FirmwareVolumesStr[Index2] == '!') { + Index2++; + } + FileName[Index1] = '\0'; + + if (Index == 0) { + // Map FV Recovery Read Only and other areas Read/Write + Status = MapFd0 ( + FileName, + &gFdInfo[0].Address, + &gFdInfo[0].Size + ); + } else { + // + // Open the FD and remember where it got mapped into our processes address space + // Maps Read Only + // + Status = MapFile ( + FileName, + &gFdInfo[Index].Address, + &gFdInfo[Index].Size + ); + } + if (EFI_ERROR (Status)) { + printf ("ERROR : Can not open Firmware Device File %s (%x). Exiting.\n", FileName, (unsigned int)Status); + exit (1); + } + + printf (" FD loaded from %s at 0x%08lx",FileName, (unsigned long)gFdInfo[Index].Address); + + if (SecFile == NULL) { + // + // Assume the beginning of the FD is an FV and look for the SEC Core. + // Load the first one we find. + // + FileHandle = NULL; + Status = PeiServicesFfsFindNextFile ( + EFI_FV_FILETYPE_SECURITY_CORE, + (EFI_PEI_FV_HANDLE)(UINTN)gFdInfo[Index].Address, + &FileHandle + ); + if (!EFI_ERROR (Status)) { + Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SecFile); + if (!EFI_ERROR (Status)) { + PeiIndex = Index; + printf (" contains SEC Core"); + } + } + } + + printf ("\n"); + } + + if (SecFile == NULL) { + printf ("ERROR : SEC not found!\n"); + exit (1); + } + + // + // Calculate memory regions and store the information in the gSystemMemory + // global for later use. The autosizing code will use this data to + // map this memory into the SEC process memory space. + // + Index1 = 0; + Index = 0; + while (1) { + UINTN val = 0; + // + // Save the size of the memory. + // + while (MemorySizeStr[Index1] >= '0' && MemorySizeStr[Index1] <= '9') { + val = val * 10 + MemorySizeStr[Index1] - '0'; + Index1++; + } + gSystemMemory[Index++].Size = val * 0x100000; + if (MemorySizeStr[Index1] == 0) { + break; + } + Index1++; + } + + printf ("\n"); + + // + // Hand off to SEC + // + SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, SecFile); + + // + // If we get here, then the SEC Core returned. This is an error as SEC should + // always hand off to PEI Core and then on to DXE Core. + // + printf ("ERROR : SEC returned\n"); + exit (1); +} + + +EFI_PHYSICAL_ADDRESS * +MapMemory ( + IN INTN fd, + IN UINT64 length, + IN INTN prot, + IN INTN flags + ) +{ + STATIC UINTN base = 0x40000000; + CONST UINTN align = (1 << 24); + VOID *res = NULL; + BOOLEAN isAligned = 0; + + // + // Try to get an aligned block somewhere in the address space of this + // process. + // + while((!isAligned) && (base != 0)) { + res = mmap ((void *)base, length, prot, flags, fd, 0); + if (res == MAP_FAILED) { + return NULL; + } + if ((((UINTN)res) & ~(align-1)) == (UINTN)res) { + isAligned=1; + } else { + munmap(res, length); + base += align; + } + } + return res; +} + + +/*++ + +Routine Description: + Opens and memory maps a file using Unix services. If BaseAddress is non zero + the process will try and allocate the memory starting at BaseAddress. + +Arguments: + FileName - The name of the file to open and map + MapSize - The amount of the file to map in bytes + CreationDisposition - The flags to pass to CreateFile(). Use to create new files for + memory emulation, and exiting files for firmware volume emulation + BaseAddress - The base address of the mapped file in the user address space. + If passed in as NULL the a new memory region is used. + If passed in as non NULL the request memory region is used for + the mapping of the file into the process space. + Length - The size of the mapped region in bytes + +Returns: + EFI_SUCCESS - The file was opened and mapped. + EFI_NOT_FOUND - FileName was not found in the current directory + EFI_DEVICE_ERROR - An error occurred attempting to map the opened file + +**/ +EFI_STATUS +MapFile ( + IN CHAR8 *FileName, + IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, + OUT UINT64 *Length + ) +{ + int fd; + VOID *res; + UINTN FileSize; + + fd = open (FileName, O_RDWR); + if (fd < 0) { + return EFI_NOT_FOUND; + } + FileSize = lseek (fd, 0, SEEK_END); + + + res = MapMemory (fd, FileSize, PROT_READ | PROT_EXEC, MAP_PRIVATE); + + close (fd); + + if (res == NULL) { + perror ("MapFile() Failed"); + return EFI_DEVICE_ERROR; + } + + *Length = (UINT64) FileSize; + *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res; + + return EFI_SUCCESS; +} + +EFI_STATUS +MapFd0 ( + IN CHAR8 *FileName, + IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, + OUT UINT64 *Length + ) +{ + int fd; + void *res, *res2, *res3; + UINTN FileSize; + UINTN FvSize; + void *EmuMagicPage; + + fd = open (FileName, O_RDWR); + if (fd < 0) { + return EFI_NOT_FOUND; + } + FileSize = lseek (fd, 0, SEEK_END); + + FvSize = FixedPcdGet64 (PcdEmuFlashFvRecoverySize); + + // Assume start of FD is Recovery FV, and make it write protected + res = mmap ( + (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase), + FvSize, + PROT_READ | PROT_EXEC, + MAP_PRIVATE, + fd, + 0 + ); + if (res == MAP_FAILED) { + perror ("MapFd0() Failed res ="); + close (fd); + return EFI_DEVICE_ERROR; + } else if (res != (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase)) { + // We could not load at the build address, so we need to allow writes + munmap (res, FvSize); + res = mmap ( + (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase), + FvSize, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE, + fd, + 0 + ); + if (res == MAP_FAILED) { + perror ("MapFd0() Failed res ="); + close (fd); + return EFI_DEVICE_ERROR; + } + } + + // Map the rest of the FD as read/write + res2 = mmap ( + (void *)(UINTN)(FixedPcdGet64 (PcdEmuFlashFvRecoveryBase) + FvSize), + FileSize - FvSize, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_SHARED, + fd, + FvSize + ); + close (fd); + if (res2 == MAP_FAILED) { + perror ("MapFd0() Failed res2 ="); + return EFI_DEVICE_ERROR; + } + + // + // If enabled use the magic page to communicate between modules + // This replaces the PI PeiServicesTable pointer mechanism that + // deos not work in the emulator. It also allows the removal of + // writable globals from SEC, PEI_CORE (libraries), PEIMs + // + EmuMagicPage = (void *)(UINTN)FixedPcdGet64 (PcdPeiServicesTablePage); + if (EmuMagicPage != NULL) { + res3 = mmap ( + (void *)EmuMagicPage, + 4096, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + 0, + 0 + ); + if (res3 != EmuMagicPage) { + printf ("MapFd0(): Could not allocate PeiServicesTablePage @ %lx\n", (long unsigned int)EmuMagicPage); + return EFI_DEVICE_ERROR; + } + } + + *Length = (UINT64) FileSize; + *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res; + + return EFI_SUCCESS; +} + + +/*++ + +Routine Description: + This is the service to load the SEC Core from the Firmware Volume + +Arguments: + LargestRegion - Memory to use for SEC. + LargestRegionSize - Size of Memory to use for PEI + BootFirmwareVolumeBase - Start of the Boot FV + PeiCorePe32File - SEC PE32 + +Returns: + Success means control is transferred and thus we should never return + +**/ +VOID +SecLoadFromCore ( + IN UINTN LargestRegion, + IN UINTN LargestRegionSize, + IN UINTN BootFirmwareVolumeBase, + IN VOID *PeiCorePe32File + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS TopOfMemory; + VOID *TopOfStack; + EFI_PHYSICAL_ADDRESS PeiCoreEntryPoint; + EFI_SEC_PEI_HAND_OFF *SecCoreData; + UINTN PeiStackSize; + + // + // Compute Top Of Memory for Stack and PEI Core Allocations + // + TopOfMemory = LargestRegion + LargestRegionSize; + PeiStackSize = (UINTN)RShiftU64((UINT64)STACK_SIZE,1); + + // + // |-----------| <---- TemporaryRamBase + TemporaryRamSize + // | Heap | + // | | + // |-----------| <---- StackBase / PeiTemporaryMemoryBase + // | | + // | Stack | + // |-----------| <---- TemporaryRamBase + // + TopOfStack = (VOID *)(LargestRegion + PeiStackSize); + TopOfMemory = LargestRegion + PeiStackSize; + + // + // Reservet space for storing PeiCore's parament in stack. + // + TopOfStack = (VOID *)((UINTN)TopOfStack - sizeof (EFI_SEC_PEI_HAND_OFF) - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + + // + // Bind this information into the SEC hand-off state + // + SecCoreData = (EFI_SEC_PEI_HAND_OFF*)(UINTN) TopOfStack; + SecCoreData->DataSize = sizeof(EFI_SEC_PEI_HAND_OFF); + SecCoreData->BootFirmwareVolumeBase = (VOID*)BootFirmwareVolumeBase; + SecCoreData->BootFirmwareVolumeSize = PcdGet32 (PcdEmuFirmwareFdSize); + SecCoreData->TemporaryRamBase = (VOID*)(UINTN)LargestRegion; + SecCoreData->TemporaryRamSize = STACK_SIZE; + SecCoreData->StackBase = SecCoreData->TemporaryRamBase; + SecCoreData->StackSize = PeiStackSize; + SecCoreData->PeiTemporaryRamBase = (VOID*) ((UINTN) SecCoreData->TemporaryRamBase + PeiStackSize); + SecCoreData->PeiTemporaryRamSize = STACK_SIZE - PeiStackSize; + + // + // Find the SEC Core Entry Point + // + Status = SecPeCoffGetEntryPoint (PeiCorePe32File, (VOID **)&PeiCoreEntryPoint); + if (EFI_ERROR (Status)) { + return ; + } + + // + // Transfer control to the SEC Core + // + PeiSwitchStacks ( + (SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint, + SecCoreData, + (VOID *)gPpiList, + TopOfStack + ); + // + // If we get here, then the SEC Core returned. This is an error + // + return ; +} + + +/*++ + +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. + It uses gSystemMemory[] and gSystemMemoryCount that were created by + parsing the host environment variable EFI_MEMORY_SIZE. + The size comes from the variable and the address comes from the call to + UnixOpenFile. + +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 + +**/ +EFI_STATUS +SecUnixPeiAutoScan ( + IN UINTN Index, + OUT EFI_PHYSICAL_ADDRESS *MemoryBase, + OUT UINT64 *MemorySize + ) +{ + void *res; + + if (Index >= gSystemMemoryCount) { + return EFI_UNSUPPORTED; + } + + *MemoryBase = 0; + res = MapMemory ( + 0, gSystemMemory[Index].Size, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS + ); + if (res == MAP_FAILED) { + return EFI_DEVICE_ERROR; + } + *MemorySize = gSystemMemory[Index].Size; + *MemoryBase = (UINTN)res; + gSystemMemory[Index].Memory = *MemoryBase; + + return EFI_SUCCESS; +} + + +/*++ + +Routine Description: + Check to see if an address range is in the EFI GCD memory map. + + This is all of GCD for system memory passed to DXE Core. FV + mapping and other device mapped into system memory are not + included in the check. + +Arguments: + Index - Which memory region to use + MemoryBase - Return Base address of memory region + MemorySize - Return size in bytes of the memory region + +Returns: + TRUE - Address is in the EFI GCD memory map + FALSE - Address is NOT in memory map + +**/ +BOOLEAN +EfiSystemMemoryRange ( + IN VOID *MemoryAddress + ) +{ + UINTN Index; + EFI_PHYSICAL_ADDRESS MemoryBase; + + MemoryBase = (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryAddress; + for (Index = 0; Index < gSystemMemoryCount; Index++) { + if ((MemoryBase >= gSystemMemory[Index].Memory) && + (MemoryBase < (gSystemMemory[Index].Memory + gSystemMemory[Index].Size)) ) { + return TRUE; + } + } + + return FALSE; +} + + +/*++ + +Routine Description: + Since the SEC is the only Unix program in stack it must export + an interface to do POSIX calls. gUnix is initialized in UnixThunk.c. + +Arguments: + InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL); + InterfaceBase - Address of the gUnix global + +Returns: + EFI_SUCCESS - Data returned + +**/ +VOID * +SecEmuThunkAddress ( + VOID + ) +{ + return &gEmuThunkProtocol; +} + + + +RETURN_STATUS +EFIAPI +SecPeCoffGetEntryPoint ( + IN VOID *Pe32Data, + IN OUT VOID **EntryPoint + ) +{ + EFI_STATUS Status; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + + ZeroMem (&ImageContext, sizeof (ImageContext)); + ImageContext.Handle = Pe32Data; + ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) SecImageRead; + + Status = PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + + if (ImageContext.ImageAddress != (UINTN)Pe32Data) { + // + // Relocate image to match the address where it resides + // + ImageContext.ImageAddress = (UINTN)Pe32Data; + Status = PeCoffLoaderLoadImage (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = PeCoffLoaderRelocateImage (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + } else { + // + // Or just return image entry point + // + ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer (Pe32Data); + Status = PeCoffLoaderGetEntryPoint (Pe32Data, EntryPoint); + if (EFI_ERROR (Status)) { + return Status; + } + ImageContext.EntryPoint = (UINTN)*EntryPoint; + } + + // On Unix a dlopen is done that will change the entry point + SecPeCoffRelocateImageExtraAction (&ImageContext); + *EntryPoint = (VOID *)(UINTN)ImageContext.EntryPoint; + + return Status; +} + + + +/*++ + +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 its 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 + +**/ +EFI_STATUS +SecUnixFdAddress ( + IN UINTN Index, + IN OUT EFI_PHYSICAL_ADDRESS *FdBase, + IN OUT UINT64 *FdSize, + IN OUT EFI_PHYSICAL_ADDRESS *FixUp + ) +{ + if (Index >= gFdInfoCount) { + return EFI_UNSUPPORTED; + } + + *FdBase = gFdInfo[Index].Address; + *FdSize = gFdInfo[Index].Size; + *FixUp = 0; + + if (*FdBase == 0 && *FdSize == 0) { + return EFI_UNSUPPORTED; + } + + if (Index == 0) { + // + // FD 0 has XIP code and well known PCD values + // If the memory buffer could not be allocated at the FD build address + // the Fixup is the difference. + // + *FixUp = *FdBase - PcdGet64 (PcdEmuFdBaseAddress); + } + + return EFI_SUCCESS; +} + + +/*++ + +Routine Description: + Count the number of separators in String + +Arguments: + String - String to process + Separator - Item to count + +Returns: + Number of Separator in String + +**/ +UINTN +CountSeparatorsInString ( + IN const CHAR16 *String, + IN CHAR16 Separator + ) +{ + UINTN Count; + + for (Count = 0; *String != '\0'; String++) { + if (*String == Separator) { + Count++; + } + } + + return Count; +} + + +EFI_STATUS +EFIAPI +SecImageRead ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ) +/*++ + +Routine Description: + Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file + +Arguments: + FileHandle - The handle to the PE/COFF file + FileOffset - The offset, in bytes, into the file to read + ReadSize - The number of bytes to read from the file starting at FileOffset + Buffer - A pointer to the buffer to read the data into. + +Returns: + EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset + +**/ +{ + CHAR8 *Destination8; + CHAR8 *Source8; + UINTN Length; + + Destination8 = Buffer; + Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); + Length = *ReadSize; + while (Length--) { + *(Destination8++) = *(Source8++); + } + + return EFI_SUCCESS; +} + + +/*++ + +Routine Description: + Store the ModHandle in an array indexed by the Pdb File name. + The ModHandle is needed to unload the image. + +Arguments: + ImageContext - Input data returned from PE Loader Library. Used to find the + .PDB file name of the PE Image. + ModHandle - Returned from LoadLibraryEx() and stored for call to + FreeLibrary(). + +Returns: + EFI_SUCCESS - ModHandle was stored. + +**/ +EFI_STATUS +AddHandle ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN VOID *ModHandle + ) +{ + UINTN Index; + IMAGE_CONTEXT_TO_MOD_HANDLE *Array; + UINTN PreviousSize; + + + Array = mImageContextModHandleArray; + for (Index = 0; Index < mImageContextModHandleArraySize; Index++, Array++) { + if (Array->ImageContext == NULL) { + // + // Make a copy of the string and store the ModHandle + // + Array->ImageContext = ImageContext; + Array->ModHandle = ModHandle; + return EFI_SUCCESS; + } + } + + // + // No free space in mImageContextModHandleArray so grow it by + // IMAGE_CONTEXT_TO_MOD_HANDLE entires. realloc will + // copy the old values to the new location. But it does + // not zero the new memory area. + // + PreviousSize = mImageContextModHandleArraySize * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE); + mImageContextModHandleArraySize += MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE; + + mImageContextModHandleArray = ReallocatePool ( + (mImageContextModHandleArraySize - 1) * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE), + mImageContextModHandleArraySize * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE), + mImageContextModHandleArray + ); + if (mImageContextModHandleArray == NULL) { + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + + memset (mImageContextModHandleArray + PreviousSize, 0, MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE * sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE)); + + return AddHandle (ImageContext, ModHandle); +} + + +/*++ + +Routine Description: + Return the ModHandle and delete the entry in the array. + +Arguments: + ImageContext - Input data returned from PE Loader Library. Used to find the + .PDB file name of the PE Image. + +Returns: + ModHandle - ModHandle associated with ImageContext is returned + NULL - No ModHandle associated with ImageContext + +**/ +VOID * +RemoveHandle ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + UINTN Index; + IMAGE_CONTEXT_TO_MOD_HANDLE *Array; + + if (ImageContext->PdbPointer == NULL) { + // + // If no PDB pointer there is no ModHandle so return NULL + // + return NULL; + } + + Array = mImageContextModHandleArray; + for (Index = 0; Index < mImageContextModHandleArraySize; Index++, Array++) { + if (Array->ImageContext == ImageContext) { + // + // If you find a match return it and delete the entry + // + Array->ImageContext = NULL; + return Array->ModHandle; + } + } + + return NULL; +} + + + +BOOLEAN +IsPdbFile ( + IN CHAR8 *PdbFileName + ) +{ + UINTN Len; + + if (PdbFileName == NULL) { + return FALSE; + } + + Len = strlen (PdbFileName); + if ((Len < 5)|| (PdbFileName[Len - 4] != '.')) { + return FALSE; + } + + if ((PdbFileName[Len - 3] == 'P' || PdbFileName[Len - 3] == 'p') && + (PdbFileName[Len - 2] == 'D' || PdbFileName[Len - 2] == 'd') && + (PdbFileName[Len - 1] == 'B' || PdbFileName[Len - 1] == 'b')) { + return TRUE; + } + + return FALSE; +} + + +#define MAX_SPRINT_BUFFER_SIZE 0x200 + +void +PrintLoadAddress ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (ImageContext->PdbPointer == NULL) { + fprintf (stderr, + "0x%08lx Loading NO DEBUG with entry point 0x%08lx\n", + (unsigned long)(ImageContext->ImageAddress), + (unsigned long)ImageContext->EntryPoint + ); + } else { + fprintf (stderr, + "0x%08lx Loading %s with entry point 0x%08lx\n", + (unsigned long)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders), + ImageContext->PdbPointer, + (unsigned long)ImageContext->EntryPoint + ); + } + // Keep output synced up + fflush (stderr); +} + + +/** + Loads the image using dlopen so symbols will be automatically + loaded by gdb. + + @param ImageContext The PE/COFF image context + + @retval TRUE - The image was successfully loaded + @retval FALSE - The image was successfully loaded + +**/ +BOOLEAN +DlLoadImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + +#ifdef __APPLE__ + + return FALSE; + +#else + + void *Handle = NULL; + void *Entry = NULL; + + if (ImageContext->PdbPointer == NULL) { + return FALSE; + } + + if (!IsPdbFile (ImageContext->PdbPointer)) { + return FALSE; + } + + fprintf ( + stderr, + "Loading %s 0x%08lx - entry point 0x%08lx\n", + ImageContext->PdbPointer, + (unsigned long)ImageContext->ImageAddress, + (unsigned long)ImageContext->EntryPoint + ); + + Handle = dlopen (ImageContext->PdbPointer, RTLD_NOW); + if (Handle != NULL) { + Entry = dlsym (Handle, "_ModuleEntryPoint"); + AddHandle (ImageContext, Handle); + } else { + printf("%s\n", dlerror()); + } + + if (Entry != NULL) { + ImageContext->EntryPoint = (UINTN)Entry; + printf ("Change %s Entrypoint to :0x%08lx\n", ImageContext->PdbPointer, (unsigned long)Entry); + return TRUE; + } else { + return FALSE; + } + +#endif +} + + +#ifdef __APPLE__ +__attribute__((noinline)) +#endif +VOID +SecGdbScriptBreak ( + char *FileName, + int FileNameLength, + long unsigned int LoadAddress, + int AddSymbolFlag + ) +{ + return; +} + + +/** + Adds the image to a gdb script so its symbols can be loaded. + The AddFirmwareSymbolFile helper macro is used. + + @param ImageContext The PE/COFF image context + +**/ +VOID +GdbScriptAddImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + + PrintLoadAddress (ImageContext); + + if (ImageContext->PdbPointer != NULL && !IsPdbFile (ImageContext->PdbPointer)) { + FILE *GdbTempFile; + if (FeaturePcdGet (PcdEmulatorLazyLoadSymbols)) { + GdbTempFile = fopen (gGdbWorkingFileName, "a"); + if (GdbTempFile != NULL) { + long unsigned int SymbolsAddr = (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders); + mScriptSymbolChangesCount++; + fprintf ( + GdbTempFile, + "AddFirmwareSymbolFile 0x%x %s 0x%08lx\n", + mScriptSymbolChangesCount, + ImageContext->PdbPointer, + SymbolsAddr + ); + fclose (GdbTempFile); + // This is for the lldb breakpoint only + SecGdbScriptBreak (ImageContext->PdbPointer, strlen (ImageContext->PdbPointer) + 1, (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders), 1); + } else { + ASSERT (FALSE); + } + } else { + GdbTempFile = fopen (gGdbWorkingFileName, "w"); + if (GdbTempFile != NULL) { + fprintf ( + GdbTempFile, + "add-symbol-file %s 0x%08lx\n", + ImageContext->PdbPointer, + (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders) + ); + fclose (GdbTempFile); + + // + // Target for gdb breakpoint in a script that uses gGdbWorkingFileName to set a breakpoint. + // Hey what can you say scripting in gdb is not that great.... + // Also used for the lldb breakpoint script. The lldb breakpoint script does + // not use the file, it uses the arguments. + // + SecGdbScriptBreak (ImageContext->PdbPointer, strlen (ImageContext->PdbPointer) + 1, (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders), 1); + } else { + ASSERT (FALSE); + } + } + } +} + + +VOID +EFIAPI +SecPeCoffRelocateImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + if (!DlLoadImage (ImageContext)) { + GdbScriptAddImage (ImageContext); + } +} + + +/** + Adds the image to a gdb script so its symbols can be unloaded. + The RemoveFirmwareSymbolFile helper macro is used. + + @param ImageContext The PE/COFF image context + +**/ +VOID +GdbScriptRemoveImage ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + FILE *GdbTempFile; + + // + // Need to skip .PDB files created from VC++ + // + if (IsPdbFile (ImageContext->PdbPointer)) { + return; + } + + if (FeaturePcdGet (PcdEmulatorLazyLoadSymbols)) { + // + // Write the file we need for the gdb script + // + GdbTempFile = fopen (gGdbWorkingFileName, "a"); + if (GdbTempFile != NULL) { + mScriptSymbolChangesCount++; + fprintf ( + GdbTempFile, + "RemoveFirmwareSymbolFile 0x%x %s\n", + mScriptSymbolChangesCount, + ImageContext->PdbPointer + ); + fclose (GdbTempFile); + SecGdbScriptBreak (ImageContext->PdbPointer, strlen (ImageContext->PdbPointer) + 1, 0, 0); + } else { + ASSERT (FALSE); + } + } else { + GdbTempFile = fopen (gGdbWorkingFileName, "w"); + if (GdbTempFile != NULL) { + fprintf (GdbTempFile, "remove-symbol-file %s\n", ImageContext->PdbPointer); + fclose (GdbTempFile); + + // + // Target for gdb breakpoint in a script that uses gGdbWorkingFileName to set a breakpoint. + // Hey what can you say scripting in gdb is not that great.... + // + SecGdbScriptBreak (ImageContext->PdbPointer, strlen (ImageContext->PdbPointer) + 1, 0, 0); + } else { + ASSERT (FALSE); + } + } +} + + +VOID +EFIAPI +SecPeCoffUnloadImageExtraAction ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + VOID *Handle; + + // + // Check to see if the image symbols were loaded with gdb script, or dlopen + // + Handle = RemoveHandle (ImageContext); + if (Handle != NULL) { +#ifndef __APPLE__ + dlclose (Handle); +#endif + return; + } + + GdbScriptRemoveImage (ImageContext); +} + + diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/Host.h b/CdeEmuPkg/EmulatorPkg/Unix/Host/Host.h new file mode 100644 index 00000000000..a5b423b04a1 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/Host.h @@ -0,0 +1,354 @@ +/*++ @file + +Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SEC_MAIN_H__ +#define _SEC_MAIN_H__ + +// +// Name mangle to prevent build errors. I.e conflicts between EFI and OS +// +#define NTOHL _UNIX_EFI_NAME_MANGLE_NTOHL_ +#define NTOHLL _UNIX_EFI_NAME_MANGLE_NTOHLL_ +#define HTONL _UNIX_EFI_NAME_MANGLE_HTONL_ +#define HTONLL _UNIX_EFI_NAME_MANGLE_HTONLL_ +#define NTOHS _UNIX_EFI_NAME_MANGLE_NTOHS_ +#define HTONS _UNIX_EFI_NAME_MANGLE_HTOHS_ +#define B0 _UNIX_EFI_NAME_MANGLE_B0_ + +#include +#include + +#include +#include +#include +#include + +#if __CYGWIN__ +#include +#else +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +#include +#include +#include +#include +#include +#define _XOPEN_SOURCE +#ifndef _Bool + #define _Bool char // for clang debug +#endif +#else +#include +#include +#include +#endif + +#include + +#undef NTOHL +#undef NTOHLL +#undef HTONL +#undef HTONLL +#undef NTOHS +#undef HTONS +#undef B0 +#undef CR3 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +#include "Gasket.h" + + +#define STACK_SIZE 0x20000 + +typedef struct { + EFI_PHYSICAL_ADDRESS Address; + UINT64 Size; +} EMU_FD_INFO; + +typedef struct { + EFI_PHYSICAL_ADDRESS Memory; + UINT64 Size; +} EMU_SYSTEM_MEMORY; + + +#define MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE 0x100 + +typedef struct { + PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext; + VOID *ModHandle; +} IMAGE_CONTEXT_TO_MOD_HANDLE; + + +EFI_STATUS +EFIAPI +SecUnixPeiLoadFile ( + VOID *Pe32Data, + EFI_PHYSICAL_ADDRESS *ImageAddress, + UINT64 *ImageSize, + EFI_PHYSICAL_ADDRESS *EntryPoint + ); + +int +main ( + IN int Argc, + IN char **Argv, + IN char **Envp + ); + +VOID +SecLoadFromCore ( + IN UINTN LargestRegion, + IN UINTN LargestRegionSize, + IN UINTN BootFirmwareVolumeBase, + IN VOID *PeiCoreFile + ); + +EFI_STATUS +SecLoadFile ( + IN VOID *Pe32Data, + IN EFI_PHYSICAL_ADDRESS *ImageAddress, + IN UINT64 *ImageSize, + IN EFI_PHYSICAL_ADDRESS *EntryPoint + ); + +EFI_STATUS +SecFfsFindPeiCore ( + IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader, + OUT VOID **Pe32Data + ); + +EFI_STATUS +SecFfsFindNextFile ( + IN EFI_FV_FILETYPE SearchType, + IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader, + IN OUT EFI_FFS_FILE_HEADER **FileHeader + ); + +EFI_STATUS +SecFfsFindSectionData ( + IN EFI_SECTION_TYPE SectionType, + IN EFI_FFS_FILE_HEADER *FfsFileHeader, + IN OUT VOID **SectionData + ); + +EFI_STATUS +EFIAPI +SecUnixPeCoffLoaderLoadAsDll ( + IN CHAR8 *PdbFileName, + IN VOID **ImageEntryPoint, + OUT VOID **ModHandle + ); + +EFI_STATUS +EFIAPI +SecUnixPeCoffLoaderFreeLibrary ( + OUT VOID *ModHandle + ); + +EFI_STATUS +SecUnixFdAddress ( + IN UINTN Index, + IN OUT EFI_PHYSICAL_ADDRESS *FdBase, + IN OUT UINT64 *FdSize, + IN OUT EFI_PHYSICAL_ADDRESS *FixUp + ) +; + +EFI_STATUS +EFIAPI +GasketSecUnixFdAddress ( + IN UINTN Index, + IN OUT EFI_PHYSICAL_ADDRESS *FdBase, + IN OUT UINT64 *FdSize, + IN OUT EFI_PHYSICAL_ADDRESS *FixUp + ) +; + + +EFI_STATUS +GetImageReadFunction ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN EFI_PHYSICAL_ADDRESS *TopOfMemory + ); + +EFI_STATUS +EFIAPI +SecImageRead ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ); + +CHAR16 * +AsciiToUnicode ( + IN CHAR8 *Ascii, + IN UINTN *StrLen OPTIONAL + ); + +UINTN +CountSeparatorsInString ( + IN const CHAR16 *String, + IN CHAR16 Separator + ); + +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + +EFI_STATUS +EFIAPI +GasketSecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + + +RETURN_STATUS +EFIAPI +SecPeCoffGetEntryPoint ( + IN VOID *Pe32Data, + IN OUT VOID **EntryPoint + ); + +VOID +EFIAPI +SecPeCoffRelocateImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + +VOID +EFIAPI +SecPeCoffLoaderUnloadImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ); + + +VOID +PeiSwitchStacks ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1, OPTIONAL + IN VOID *Context2, OPTIONAL + IN VOID *NewStack + ); + +VOID +SecInitThunkProtocol ( + VOID + ); + + +EFI_PHYSICAL_ADDRESS * +MapMemory ( + INTN fd, + UINT64 length, + INTN prot, + INTN flags); + +EFI_STATUS +MapFile ( + IN CHAR8 *FileName, + IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, + OUT UINT64 *Length + ); + +EFI_STATUS +MapFd0 ( + IN CHAR8 *FileName, + IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress, + OUT UINT64 *Length + ); + +BOOLEAN +EfiSystemMemoryRange ( + IN VOID *MemoryAddress + ); + + +VOID SecSleep (UINT64 Nanoseconds); +VOID SecEnableInterrupt (VOID); +VOID SecDisableInterrupt (VOID); +BOOLEAN SecInterruptEanbled (VOID); + + +extern EMU_THUNK_PROTOCOL gEmuThunkProtocol; +extern EMU_IO_THUNK_PROTOCOL gX11ThunkIo; +extern EMU_IO_THUNK_PROTOCOL gPosixFileSystemThunkIo; +extern EMU_IO_THUNK_PROTOCOL gPthreadThunkIo; +extern EMU_IO_THUNK_PROTOCOL gBlockIoThunkIo; +extern EMU_IO_THUNK_PROTOCOL gSnpThunkIo; + +#endif diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/Host.inf b/CdeEmuPkg/EmulatorPkg/Unix/Host/Host.inf new file mode 100644 index 00000000000..732ddc90ecc --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/Host.inf @@ -0,0 +1,142 @@ +## @file +# Entry Point of Emu Emulator +# +# Main executable file of Unix Emulator that loads PEI core after initialization finished. +# Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Host + FILE_GUID = 8863C0AD-7724-C84B-88E5-A33B116D1485 + MODULE_TYPE = USER_DEFINED + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + Host.c + EmuThunk.c + X11GraphicsWindow.c + Pthreads.c + PosixFileSystem.c + BlockIo.c + LinuxPacketFilter.c + BerkeleyPacketFilter.c + MemoryAllocationLib.c + +[Sources.X64] + X64/Gasket.S # convert between Emu x86_64 ABI and EFI X64 ABI + X64/SwitchStack.S + +[Sources.IA32] + Ia32/Gasket.S # enforce 16-byte stack alignment for Mac OS X + Ia32/SwitchStack.c + + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + NetworkPkg/NetworkPkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + DebugLib + PcdLib + PrintLib + BaseMemoryLib + BaseLib + PeCoffLib + ThunkPpiList + ThunkProtocolList + PpiListLib + PeiServicesLib + PeCoffGetEntryPointLib + +[Ppis] + gEfiPeiStatusCodePpiGuid # PPI ALWAYS_PRODUCED + gEmuThunkPpiGuid + +[Protocols] + gEmuIoThunkProtocolGuid + gEmuIoThunkProtocolGuid + gEmuGraphicsWindowProtocolGuid + gEmuThreadThunkProtocolGuid + gEmuBlockIoProtocolGuid + gEmuSnpProtocolGuid + gEfiSimpleFileSystemProtocolGuid + +[Guids] + gEfiFileSystemVolumeLabelInfoIdGuid # SOMETIMES_CONSUMED + gEfiFileInfoGuid # SOMETIMES_CONSUMED + gEfiFileSystemInfoGuid # SOMETIMES_CONSUMED + +[Pcd] + gEmulatorPkgTokenSpaceGuid.PcdEmuBootMode + gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareVolume + gEmulatorPkgTokenSpaceGuid.PcdEmuMemorySize + gEmulatorPkgTokenSpaceGuid.PcdEmuFdBaseAddress + gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareFdSize + gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareBlockSize + gEmulatorPkgTokenSpaceGuid.PcdEmuApCount + gEmulatorPkgTokenSpaceGuid.PcdEmuVirtualDisk + gEmulatorPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window" + gEmulatorPkgTokenSpaceGuid.PcdEmuFileSystem + gEmulatorPkgTokenSpaceGuid.PcdEmuSerialPort + gEmulatorPkgTokenSpaceGuid.PcdEmuNetworkInterface + gEmulatorPkgTokenSpaceGuid.PcdNetworkPacketFilterSize + + gEmulatorPkgTokenSpaceGuid.PcdEmuFlashFvRecoveryBase + gEmulatorPkgTokenSpaceGuid.PcdEmuFlashFvRecoverySize + gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogBase + gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageEventLogSize + gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEmulatorPkgTokenSpaceGuid.PcdEmuFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage + +[FeaturePcd] + gEmulatorPkgTokenSpaceGuid.PcdEmulatorLazyLoadSymbols + + +[BuildOptions] + GCC:*_*_IA32_DLINK_FLAGS == -o $(BIN_DIR)/Host -m32 -L/usr/X11R6/lib + GCC:*_*_IA32_CC_FLAGS == -m32 -g -fshort-wchar -fno-strict-aliasing -Wall -malign-double -idirafter/usr/include -c -include $(DEST_DIR_DEBUG)/AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings + GCC:*_*_IA32_PP_FLAGS == -m32 -E -x assembler-with-cpp -include $(DEST_DIR_DEBUG)/AutoGen.h + GCC:*_*_IA32_ASM_FLAGS == -m32 -c -x assembler -imacros $(DEST_DIR_DEBUG)/AutoGen.h + + GCC:*_*_X64_DLINK_FLAGS == -o $(BIN_DIR)/Host -m64 -L/usr/X11R6/lib + GCC:*_GCC5_X64_DLINK_FLAGS == -flto -o $(BIN_DIR)/Host -m64 -L/usr/X11R6/lib + GCC:*_*_X64_CC_FLAGS == -m64 -g -fshort-wchar -fno-strict-aliasing -Wall -malign-double -idirafter/usr/include -c -include $(DEST_DIR_DEBUG)/AutoGen.h -DSTRING_ARRAY_NAME=$(BASE_NAME)Strings + GCC:*_GCC48_X64_CC_FLAGS = "-DEFIAPI=__attribute__((ms_abi))" + GCC:*_GCC49_X64_CC_FLAGS = "-DEFIAPI=__attribute__((ms_abi))" + GCC:*_GCC5_X64_CC_FLAGS = "-DEFIAPI=__attribute__((ms_abi))" -flto -DUSING_LTO -Os + GCC:*_*_X64_PP_FLAGS == -m64 -E -x assembler-with-cpp -include $(DEST_DIR_DEBUG)/AutoGen.h + GCC:*_*_X64_ASM_FLAGS == -m64 -c -x assembler -imacros $(DEST_DIR_DEBUG)/AutoGen.h + + GCC:*_*_*_DLINK2_FLAGS == -lpthread -ldl -lXext -lX11 + +# +# Need to do this link via gcc and not ld as the pathing to libraries changes from OS version to OS version +# + XCODE:*_*_IA32_DLINK_PATH == gcc + XCODE:*_*_IA32_CC_FLAGS = -I$(WORKSPACE)/EmulatorPkg/Unix/Host/X11IncludeHack + XCODE:*_*_IA32_DLINK_FLAGS == -arch i386 -o $(BIN_DIR)/Host -L/usr/X11R6/lib -lXext -lX11 -framework Carbon + XCODE:*_*_IA32_ASM_FLAGS == -arch i386 -g + + XCODE:*_*_X64_DLINK_PATH == gcc + XCODE:*_*_X64_DLINK_FLAGS == -o $(BIN_DIR)/Host -L/usr/X11R6/lib -lXext -lX11 -framework Carbon -Wl,-no_pie + XCODE:*_*_X64_ASM_FLAGS == -g + XCODE:*_*_X64_CC_FLAGS = -O0 -target x86_64-apple-darwin -I$(WORKSPACE)/EmulatorPkg/Unix/Host/X11IncludeHack "-DEFIAPI=__attribute__((ms_abi))" diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/Ia32/Gasket.S b/CdeEmuPkg/EmulatorPkg/Unix/Host/Ia32/Gasket.S new file mode 100644 index 00000000000..70ed2a1811c --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/Ia32/Gasket.S @@ -0,0 +1,1486 @@ +#------------------------------------------------------------------------------ +# +# Manage differenced between UNIX ABI and EFI/Windows ABI +# +# For IA-32 the only difference is Mac OS X requires a 16-byte aligned stack. +# For Linux this stack adjustment is a no-op, but we may as well make the +# the code common. +# +# Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#------------------------------------------------------------------------------ + + + + .text + +// +// EMU_THUNK_PROTOCOL gaskets (EFIAPI to UNIX ABI) +// + + +ASM_GLOBAL ASM_PFX(GasketSecWriteStdErr) +ASM_PFX(GasketSecWriteStdErr): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecWriteStdErr) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSecConfigStdIn) +ASM_PFX(GasketSecConfigStdIn): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecConfigStdIn) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketSecWriteStdOut) +ASM_PFX(GasketSecWriteStdOut): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecWriteStdOut) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketSecReadStdIn) +ASM_PFX(GasketSecReadStdIn): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecReadStdIn) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketSecPollStdIn) +ASM_PFX(GasketSecPollStdIn): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecPollStdIn) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketSecMalloc) +ASM_PFX(GasketSecMalloc): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecMalloc) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketSecValloc) +ASM_PFX(GasketSecValloc): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecValloc) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketSecFree) +ASM_PFX(GasketSecFree): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecFree) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSecSetTimer) +ASM_PFX(GasketSecSetTimer): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 8(%ebp), %eax + movl 12(%ebp), %edx + movl %edx, 4(%esp) + movl %eax, (%esp) + + call ASM_PFX(SecSetTimer) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSecEnableInterrupt) +ASM_PFX(GasketSecEnableInterrupt): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + + call ASM_PFX(SecEnableInterrupt) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSecDisableInterrupt) +ASM_PFX(GasketSecDisableInterrupt): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + + call ASM_PFX(SecDisableInterrupt) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketQueryPerformanceFrequency) +ASM_PFX(GasketQueryPerformanceFrequency): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + + call ASM_PFX(QueryPerformanceFrequency) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketQueryPerformanceCounter) +ASM_PFX(GasketQueryPerformanceCounter): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + + call ASM_PFX(QueryPerformanceCounter) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSecSleep) +ASM_PFX(GasketSecSleep): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl 12(%ebp), %ecx + movl %ecx, 4(%esp) + movl %eax, (%esp) + + call ASM_PFX(SecSleep) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSecCpuSleep) +ASM_PFX(GasketSecCpuSleep): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + + call ASM_PFX(SecCpuSleep) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSecExit) +ASM_PFX(GasketSecExit): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecExit) // Less to do as we will never return to EFI ABI world +LDEAD_LOOP: + jmp LDEAD_LOOP // _exit should never return + + +ASM_GLOBAL ASM_PFX(GasketSecGetTime) +ASM_PFX(GasketSecGetTime): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecGetTime) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketSecSetTime) +ASM_PFX(GasketSecSetTime): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecSetTime) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSecGetNextProtocol) +ASM_PFX(GasketSecGetNextProtocol): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecGetNextProtocol) + + leave + ret + +// PPIs produced by SEC + +ASM_GLOBAL ASM_PFX(GasketSecPeCoffGetEntryPoint) +ASM_PFX(GasketSecPeCoffGetEntryPoint): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecPeCoffGetEntryPoint) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketSecPeCoffRelocateImageExtraAction) +ASM_PFX(GasketSecPeCoffRelocateImageExtraAction): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecPeCoffRelocateImageExtraAction) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketSecPeCoffUnloadImageExtraAction) +ASM_PFX(GasketSecPeCoffUnloadImageExtraAction): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecPeCoffUnloadImageExtraAction) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSecEmuThunkAddress) +ASM_PFX(GasketSecEmuThunkAddress): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + + call ASM_PFX(SecEmuThunkAddress) + + leave + ret + +// +// Gasket functions for EFI_EMU_UGA_IO_PROTOCOL +// + +ASM_GLOBAL ASM_PFX(GasketX11Size) +ASM_PFX(GasketX11Size): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(X11Size) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketX11CheckKey) +ASM_PFX(GasketX11CheckKey): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(X11CheckKey) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketX11GetKey) +ASM_PFX(GasketX11GetKey): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(X11GetKey) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketX11KeySetState) +ASM_PFX(GasketX11KeySetState): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(X11KeySetState) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketX11RegisterKeyNotify) +ASM_PFX(GasketX11RegisterKeyNotify): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(X11RegisterKeyNotify) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketX11Blt) +ASM_PFX(GasketX11Blt): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(X11Blt) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketX11CheckPointer) +ASM_PFX(GasketX11CheckPointer): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(X11CheckPointer) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketX11GetPointerState) +ASM_PFX(GasketX11GetPointerState): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(X11GetPointerState) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketX11GraphicsWindowOpen) +ASM_PFX(GasketX11GraphicsWindowOpen): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(X11GraphicsWindowOpen) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketX11GraphicsWindowClose) +ASM_PFX(GasketX11GraphicsWindowClose): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(X11GraphicsWindowClose) + + leave + ret + + +// Pthreads + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexLock) +ASM_PFX(GasketPthreadMutexLock): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PthreadMutexLock) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexUnLock) +ASM_PFX(GasketPthreadMutexUnLock): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PthreadMutexUnLock) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexTryLock) +ASM_PFX(GasketPthreadMutexTryLock): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PthreadMutexTryLock) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexInit) +ASM_PFX(GasketPthreadMutexInit): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + + call ASM_PFX(PthreadMutexInit) + + leave + ret + + + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexDestroy) +ASM_PFX(GasketPthreadMutexDestroy): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PthreadMutexDestroy) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadCreate) +ASM_PFX(GasketPthreadCreate): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PthreadCreate) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadExit) +ASM_PFX(GasketPthreadExit): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PthreadExit) + + leave + ret + + + +ASM_GLOBAL ASM_PFX(GasketPthreadSelf) +ASM_PFX(GasketPthreadSelf): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + + call ASM_PFX(PthreadSelf) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadOpen) +ASM_PFX(GasketPthreadOpen): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PthreadOpen) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadClose) +ASM_PFX(GasketPthreadClose): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PthreadClose) + + leave + ret + + + + +// +// UNIX ABI to EFI ABI call +// +// UINTN +// ReverseGasketUint64 ( +// void *Api, +// UINTN Arg1 +// ); +ASM_GLOBAL ASM_PFX(ReverseGasketUint64) +ASM_PFX(ReverseGasketUint64): + pushl %ebp + movl %esp, %ebp + subl $8, %esp + movl 16(%ebp), %eax + movl %eax, 4(%esp) + movl 12(%ebp), %eax + movl %eax, (%esp) + calll *8(%ebp) + addl $8, %esp + popl %ebp + ret + + + +// +// UNIX ABI to EFI ABI call +// +// UINTN +// ReverseGasketUint64Uint64 ( +// void *Api, +// UINTN Arg1 +// UINTN Arg2 +// ); +ASM_GLOBAL ASM_PFX(ReverseGasketUint64Uint64) +ASM_PFX(ReverseGasketUint64Uint64): + pushl %ebp + movl %esp, %ebp + subl $24, %esp + movl 24(%ebp), %eax + movl %eax, 12(%esp) + movl 20(%ebp), %eax + movl %eax, 8(%esp) + movl 16(%ebp), %eax + movl %eax, 4(%esp) + movl 12(%ebp), %eax + movl %eax, (%esp) + calll *8(%ebp) + addl $24, %esp + popl %ebp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecUnixPeiAutoScan) +ASM_PFX(GasketSecUnixPeiAutoScan): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecUnixPeiAutoScan) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSecUnixFdAddress) +ASM_PFX(GasketSecUnixFdAddress): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(SecUnixFdAddress) + + leave + ret + + +// EmuIoThunk SimpleFileSystem + +ASM_GLOBAL ASM_PFX(GasketPosixOpenVolume) +ASM_PFX(GasketPosixOpenVolume): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PosixOpenVolume) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileOpen) +ASM_PFX(GasketPosixFileOpen): + pushl %ebp + movl %esp, %ebp + subl $56, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 28(%ebp), %eax + movl 32(%ebp), %ecx + movl %ecx, 24(%esp) + movl %eax, 20(%esp) + movl 20(%ebp), %eax + movl 24(%ebp), %ecx + movl %ecx, 16(%esp) + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PosixFileOpen) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileCLose) +ASM_PFX(GasketPosixFileCLose): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PosixFileCLose) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileDelete) +ASM_PFX(GasketPosixFileDelete): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PosixFileDelete) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileRead) +ASM_PFX(GasketPosixFileRead): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PosixFileRead) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileWrite) +ASM_PFX(GasketPosixFileWrite): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PosixFileWrite) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileSetPossition) +ASM_PFX(GasketPosixFileSetPossition): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl 16(%ebp), %ecx + movl %ecx, 8(%esp) + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PosixFileSetPossition) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileGetPossition) +ASM_PFX(GasketPosixFileGetPossition): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PosixFileGetPossition) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileGetInfo) +ASM_PFX(GasketPosixFileGetInfo): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PosixFileGetInfo) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileSetInfo) +ASM_PFX(GasketPosixFileSetInfo): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PosixFileSetInfo) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileFlush) +ASM_PFX(GasketPosixFileFlush): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PosixFileFlush) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileSystmeThunkOpen) +ASM_PFX(GasketPosixFileSystmeThunkOpen): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PosixFileSystmeThunkOpen) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileSystmeThunkClose) +ASM_PFX(GasketPosixFileSystmeThunkClose): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(PosixFileSystmeThunkClose) + + leave + ret + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoReset) +ASM_PFX(GasketEmuBlockIoReset): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuBlockIoReset) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoReadBlocks) +ASM_PFX(GasketEmuBlockIoReadBlocks): + pushl %ebp + movl %esp, %ebp + subl $56, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 32(%ebp), %eax + movl %eax, 24(%esp) + movl 28(%ebp), %eax + movl %eax, 20(%esp) + movl 24(%ebp), %eax + movl %eax, 16(%esp) + movl 16(%ebp), %eax + movl 20(%ebp), %edx + movl %edx, 12(%esp) + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuBlockIoReadBlocks) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoWriteBlocks) +ASM_PFX(GasketEmuBlockIoWriteBlocks): + pushl %ebp + movl %esp, %ebp + subl $56, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 32(%ebp), %eax + movl %eax, 24(%esp) + movl 28(%ebp), %eax + movl %eax, 20(%esp) + movl 24(%ebp), %eax + movl %eax, 16(%esp) + movl 16(%ebp), %eax + movl 20(%ebp), %edx + movl %edx, 12(%esp) + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuBlockIoWriteBlocks) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoFlushBlocks) +ASM_PFX(GasketEmuBlockIoFlushBlocks): pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + + call ASM_PFX(EmuBlockIoFlushBlocks) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoCreateMapping) +ASM_PFX(GasketEmuBlockIoCreateMapping): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuBlockIoCreateMapping) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketBlockIoThunkOpen) +ASM_PFX(GasketBlockIoThunkOpen): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuBlockIoThunkOpen) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketBlockIoThunkClose) +ASM_PFX(GasketBlockIoThunkClose): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuBlockIoThunkClose) + + leave + ret + + + +ASM_GLOBAL ASM_PFX(GasketSnpCreateMapping) +ASM_PFX(GasketSnpCreateMapping): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpCreateMapping) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpStart) +ASM_PFX(GasketSnpStart): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpStart) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpStop) +ASM_PFX(GasketSnpStop): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpStop) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpInitialize) +ASM_PFX(GasketSnpInitialize): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpInitialize) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpReset) +ASM_PFX(GasketSnpReset): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpReset) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpShutdown) +ASM_PFX(GasketSnpShutdown): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpShutdown) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpReceiveFilters) +ASM_PFX(GasketSnpReceiveFilters): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 28(%ebp), %eax + movl %eax, 20(%esp) + movl 24(%ebp), %eax + movl %eax, 16(%esp) + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpReceiveFilters) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpStationAddress) +ASM_PFX(GasketSnpStationAddress): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + leave + ret + + + +ASM_GLOBAL ASM_PFX(GasketSnpStatistics) +ASM_PFX(GasketSnpStatistics): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpStatistics) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpMCastIpToMac) +ASM_PFX(GasketSnpMCastIpToMac): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpMCastIpToMac) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpNvData) +ASM_PFX(GasketSnpNvData): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 24(%ebp), %eax + movl %eax, 16(%esp) + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpNvData) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpGetStatus) +ASM_PFX(GasketSnpGetStatus): + pushl %ebp + movl %esp, %ebp + subl $40, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpGetStatus) + + leave + ret + + + +ASM_GLOBAL ASM_PFX(GasketSnpTransmit) +ASM_PFX(GasketSnpTransmit): + pushl %ebp + movl %esp, %ebp + subl $56, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 32(%ebp), %eax + movl %eax, 24(%esp) + movl 28(%ebp), %eax + movl %eax, 20(%esp) + movl 24(%ebp), %eax + movl %eax, 16(%esp) + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpTransmit) + + leave + ret + + + +ASM_GLOBAL ASM_PFX(GasketSnpReceive) +ASM_PFX(GasketSnpReceive): + pushl %ebp + movl %esp, %ebp + subl $56, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 32(%ebp), %eax + movl %eax, 24(%esp) + movl 28(%ebp), %eax + movl %eax, 20(%esp) + movl 24(%ebp), %eax + movl %eax, 16(%esp) + movl 20(%ebp), %eax + movl %eax, 12(%esp) + movl 16(%ebp), %eax + movl %eax, 8(%esp) + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpReceive) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpThunkOpen) +ASM_PFX(GasketSnpThunkOpen): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpThunkOpen) + + leave + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpThunkClose) +ASM_PFX(GasketSnpThunkClose): + pushl %ebp + movl %esp, %ebp + subl $24, %esp // sub extra 16 from the stack for alignment + and $-16, %esp // stack needs to end in 0xFFFFFFF0 before call + movl 8(%ebp), %eax + movl %eax, (%esp) + + call ASM_PFX(EmuSnpThunkClose) + + leave + ret + + diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/Ia32/SwitchStack.c b/CdeEmuPkg/EmulatorPkg/Unix/Host/Ia32/SwitchStack.c new file mode 100644 index 00000000000..b4d4b0e4d2d --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/Ia32/SwitchStack.c @@ -0,0 +1,68 @@ +/*++ + +Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + + +--*/ + +#include "Host.h" + + +/** + Transfers control to a function starting with a new stack. + + Transfers control to the function specified by EntryPoint using the new stack + specified by NewStack and passing in the parameters specified by Context1 and + Context2. Context1 and Context2 are optional and may be NULL. The function + EntryPoint must never return. + + If EntryPoint is NULL, then ASSERT(). + If NewStack is NULL, then ASSERT(). + + @param EntryPoint A pointer to function to call with the new stack. + @param Context1 A pointer to the context to pass into the EntryPoint + function. + @param Context2 A pointer to the context to pass into the EntryPoint + function. + @param NewStack A pointer to the new stack to use for the EntryPoint + function. + +**/ +VOID +EFIAPI +PeiSwitchStacks ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1, OPTIONAL + IN VOID *Context2, OPTIONAL + IN VOID *NewStack + ) +{ + BASE_LIBRARY_JUMP_BUFFER JumpBuffer; + + ASSERT (EntryPoint != NULL); + ASSERT (NewStack != NULL); + + // + // Stack should be aligned with CPU_STACK_ALIGNMENT + // + ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0); + + JumpBuffer.Eip = (UINTN)EntryPoint; + JumpBuffer.Esp = (UINTN)NewStack - sizeof (VOID*); + JumpBuffer.Esp -= sizeof (Context1) + sizeof (Context2); + ((VOID**)JumpBuffer.Esp)[1] = Context1; + ((VOID**)JumpBuffer.Esp)[2] = Context2; + + LongJump (&JumpBuffer, (UINTN)-1); + + + // + // PeiSwitchStacks () will never return + // + ASSERT (FALSE); +} + + + diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/LinuxPacketFilter.c b/CdeEmuPkg/EmulatorPkg/Unix/Host/LinuxPacketFilter.c new file mode 100644 index 00000000000..af91b181a11 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/LinuxPacketFilter.c @@ -0,0 +1,598 @@ +/**@file + Linux Packet Filter implementation of the EMU_SNP_PROTOCOL that allows the + emulator to get on real networks. + + Currently only the Berkeley Packet Filter is fully implemented and this file + is just a template that needs to get filled in. + +Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.
+Portions copyright (c) 2011, Apple Inc. All rights reserved. + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + + +#include "Host.h" + +#ifndef __APPLE__ + +#define EMU_SNP_PRIVATE_SIGNATURE SIGNATURE_32('E', 'M', 's', 'n') +typedef struct { + UINTN Signature; + + EMU_IO_THUNK_PROTOCOL *Thunk; + + + EMU_SNP_PROTOCOL EmuSnp; + EFI_SIMPLE_NETWORK_MODE *Mode; + +} EMU_SNP_PRIVATE; + +#define EMU_SNP_PRIVATE_DATA_FROM_THIS(a) \ + CR(a, EMU_SNP_PRIVATE, EmuSnp, EMU_SNP_PRIVATE_SIGNATURE) + +/** + 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. + +**/ +EFI_STATUS +EmuSnpCreateMapping ( + IN EMU_SNP_PROTOCOL *This, + IN EFI_SIMPLE_NETWORK_MODE *Mode + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + Private->Mode = Mode; + + return EFI_SUCCESS; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpStart ( + IN EMU_SNP_PROTOCOL *This + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpStop ( + IN EMU_SNP_PROTOCOL *This + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpInitialize ( + IN EMU_SNP_PROTOCOL *This, + IN UINTN ExtraRxBufferSize OPTIONAL, + IN UINTN ExtraTxBufferSize OPTIONAL + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpReset ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpShutdown ( + IN EMU_SNP_PROTOCOL *This + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpReceiveFilters ( + IN EMU_SNP_PROTOCOL *This, + IN UINT32 Enable, + IN UINT32 Disable, + IN BOOLEAN ResetMCastFilter, + IN UINTN MCastFilterCnt OPTIONAL, + IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpStationAddress ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN Reset, + IN EFI_MAC_ADDRESS *New OPTIONAL + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpStatistics ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN Reset, + IN OUT UINTN *StatisticsSize OPTIONAL, + OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpMCastIpToMac ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN IPv6, + IN EFI_IP_ADDRESS *IP, + OUT EFI_MAC_ADDRESS *MAC + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpNvData ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN ReadWrite, + IN UINTN Offset, + IN UINTN BufferSize, + IN OUT VOID *Buffer + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpGetStatus ( + IN EMU_SNP_PROTOCOL *This, + OUT UINT32 *InterruptStatus OPTIONAL, + OUT VOID **TxBuf OPTIONAL + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpTransmit ( + 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 + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +EmuSnpReceive ( + 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 + ) +{ + EMU_SNP_PRIVATE *Private; + + Private = EMU_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + + +EMU_SNP_PROTOCOL gEmuSnpProtocol = { + GasketSnpCreateMapping, + GasketSnpStart, + GasketSnpStop, + GasketSnpInitialize, + GasketSnpReset, + GasketSnpShutdown, + GasketSnpReceiveFilters, + GasketSnpStationAddress, + GasketSnpStatistics, + GasketSnpMCastIpToMac, + GasketSnpNvData, + GasketSnpGetStatus, + GasketSnpTransmit, + GasketSnpReceive +}; + +EFI_STATUS +EmuSnpThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + EMU_SNP_PRIVATE *Private; + + if (This->Private != NULL) { + return EFI_ALREADY_STARTED; + } + + if (!CompareGuid (This->Protocol, &gEmuSnpProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + Private = malloc (sizeof (EMU_SNP_PRIVATE)); + if (Private == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + + Private->Signature = EMU_SNP_PRIVATE_SIGNATURE; + Private->Thunk = This; + CopyMem (&Private->EmuSnp, &gEmuSnpProtocol, sizeof (gEmuSnpProtocol)); + + This->Interface = &Private->EmuSnp; + This->Private = Private; + return EFI_SUCCESS; +} + + +EFI_STATUS +EmuSnpThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + EMU_SNP_PRIVATE *Private; + + if (!CompareGuid (This->Protocol, &gEmuSnpProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + Private = This->Private; + free (Private); + + return EFI_SUCCESS; +} + + + +EMU_IO_THUNK_PROTOCOL gSnpThunkIo = { + &gEmuSnpProtocolGuid, + NULL, + NULL, + 0, + GasketSnpThunkOpen, + GasketSnpThunkClose, + NULL +}; + +#endif diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/MemoryAllocationLib.c b/CdeEmuPkg/EmulatorPkg/Unix/Host/MemoryAllocationLib.c new file mode 100644 index 00000000000..6caccd4ebd7 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/MemoryAllocationLib.c @@ -0,0 +1,139 @@ +/*++ @file + + Copyright (c) 2011, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Base.h" +#include "Library/BaseMemoryLib.h" +#include "Library/MemoryAllocationLib.h" + +#include + +/** + Allocates a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocatePool ( + IN UINTN AllocationSize + ) +{ + return (VOID*) malloc (AllocationSize); +} + + +/** + Allocates and zeros a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateZeroPool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = AllocatePool (AllocationSize); + if (Buffer == NULL) { + return NULL; + } + + ZeroMem (Buffer, AllocationSize); + + return Buffer; +} + + +/** + Reallocates a buffer of type EfiBootServicesData. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocatePool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + VOID *NewBuffer; + + NewBuffer = AllocatePool (NewSize); + if (NewBuffer == NULL) { + return NULL; + } + + if (OldBuffer != NULL) { + if (OldSize > 0) { + CopyMem (NewBuffer, OldBuffer, OldSize); + } + + FreePool (OldBuffer); + } + + return NewBuffer; +} + + +/** + Frees a buffer that was previously allocated with one of the pool allocation functions in the + Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + pool allocation services of the Memory Allocation Library. If it is not possible to free pool + resources, then this function will perform no actions. + + If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, + then ASSERT(). + + @param Buffer Pointer to the buffer to free. + +**/ +VOID +EFIAPI +FreePool ( + IN VOID *Buffer + ) +{ + free ((void *) Buffer); +} + diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/PosixFileSystem.c b/CdeEmuPkg/EmulatorPkg/Unix/Host/PosixFileSystem.c new file mode 100644 index 00000000000..0822332cc33 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/PosixFileSystem.c @@ -0,0 +1,1587 @@ +/*++ @file + POSIX Pthreads to emulate APs and implement threads + +Copyright (c) 2011, Apple Inc. All rights reserved. +Copyright (c) 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + + +**/ + +#include "Host.h" + + +#define EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE SIGNATURE_32 ('E', 'P', 'f', 's') + +typedef struct { + UINTN Signature; + EMU_IO_THUNK_PROTOCOL *Thunk; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystem; + CHAR8 *FilePath; + CHAR16 *VolumeLabel; + BOOLEAN FileHandlesOpen; +} 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', 'P', 'f', 'i') + +typedef struct { + UINTN Signature; + EMU_IO_THUNK_PROTOCOL *Thunk; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem; + EFI_FILE_PROTOCOL EfiFile; + int fd; + DIR *Dir; + BOOLEAN IsRootDirectory; + BOOLEAN IsDirectoryPath; + BOOLEAN IsOpenedByRead; + char *FileName; + struct dirent *Dirent; +} 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 \ + ) + +EFI_STATUS +PosixFileGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +EFI_STATUS +PosixFileSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ); + + +EFI_FILE_PROTOCOL gPosixFileProtocol = { + EFI_FILE_REVISION, + GasketPosixFileOpen, + GasketPosixFileCLose, + GasketPosixFileDelete, + GasketPosixFileRead, + GasketPosixFileWrite, + GasketPosixFileGetPossition, + GasketPosixFileSetPossition, + GasketPosixFileGetInfo, + GasketPosixFileSetInfo, + GasketPosixFileFlush +}; + +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gPosixFileSystemProtocol = { + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION, + GasketPosixOpenVolume, +}; + + +/** + 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 +PosixOpenVolume ( + 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; + + Private = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This); + + Status = EFI_OUT_OF_RESOURCES; + PrivateFile = malloc (sizeof (EMU_EFI_FILE_PRIVATE)); + if (PrivateFile == NULL) { + goto Done; + } + + PrivateFile->FileName = malloc (AsciiStrSize (Private->FilePath)); + if (PrivateFile->FileName == NULL) { + goto Done; + } + AsciiStrCpyS ( + PrivateFile->FileName, + AsciiStrSize (Private->FilePath), + Private->FilePath + ); + + PrivateFile->Signature = EMU_EFI_FILE_PRIVATE_SIGNATURE; + PrivateFile->Thunk = Private->Thunk; + PrivateFile->SimpleFileSystem = This; + PrivateFile->IsRootDirectory = TRUE; + PrivateFile->IsDirectoryPath = TRUE; + PrivateFile->IsOpenedByRead = TRUE; + + CopyMem (&PrivateFile->EfiFile, &gPosixFileProtocol, sizeof (EFI_FILE_PROTOCOL)); + + PrivateFile->fd = -1; + PrivateFile->Dir = NULL; + PrivateFile->Dirent = NULL; + + *Root = &PrivateFile->EfiFile; + + PrivateFile->Dir = opendir (PrivateFile->FileName); + if (PrivateFile->Dir == NULL) { + Status = EFI_ACCESS_DENIED; + } else { + Status = EFI_SUCCESS; + } + +Done: + if (EFI_ERROR (Status)) { + if (PrivateFile != NULL) { + if (PrivateFile->FileName != NULL) { + free (PrivateFile->FileName); + } + + free (PrivateFile); + } + + *Root = NULL; + } + + return Status; +} + + +EFI_STATUS +ErrnoToEfiStatus () +{ + switch (errno) { + case EACCES: + return EFI_ACCESS_DENIED; + + case EDQUOT: + case ENOSPC: + return EFI_VOLUME_FULL; + + default: + return EFI_DEVICE_ERROR; + } +} + +VOID +CutPrefix ( + IN CHAR8 *Str, + IN UINTN Count + ) +{ + CHAR8 *Pointer; + + if (AsciiStrLen (Str) < Count) { + ASSERT (0); + } + + for (Pointer = Str; *(Pointer + Count); Pointer++) { + *Pointer = *(Pointer + Count); + } + + *Pointer = *(Pointer + Count); +} + + +VOID +PosixSystemTimeToEfiTime ( + IN time_t SystemTime, + OUT EFI_TIME *Time + ) +{ + struct tm *tm; + + tm = gmtime (&SystemTime); + Time->Year = tm->tm_year; + Time->Month = tm->tm_mon + 1; + Time->Day = tm->tm_mday; + Time->Hour = tm->tm_hour; + Time->Minute = tm->tm_min; + Time->Second = tm->tm_sec; + Time->Nanosecond = 0; + + Time->TimeZone = timezone / 60; + Time->Daylight = (daylight ? EFI_TIME_ADJUST_DAYLIGHT : 0) | (tm->tm_isdst > 0 ? EFI_TIME_IN_DAYLIGHT : 0); +} + + +EFI_STATUS +UnixSimpleFileSystemFileInfo ( + EMU_EFI_FILE_PRIVATE *PrivateFile, + IN CHAR8 *FileName, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + UINTN Size; + UINTN NameSize; + UINTN ResultSize; + EFI_FILE_INFO *Info; + CHAR8 *RealFileName; + CHAR8 *TempPointer; + CHAR16 *BufferFileName; + struct stat buf; + + if (FileName != NULL) { + RealFileName = FileName; + } else if (PrivateFile->IsRootDirectory) { + RealFileName = ""; + } else { + RealFileName = PrivateFile->FileName; + } + + TempPointer = RealFileName; + while (*TempPointer) { + if (*TempPointer == '/') { + RealFileName = TempPointer + 1; + } + + TempPointer++; + } + + Size = SIZE_OF_EFI_FILE_INFO; + NameSize = AsciiStrSize (RealFileName) * 2; + ResultSize = Size + NameSize; + + if (*BufferSize < ResultSize) { + *BufferSize = ResultSize; + return EFI_BUFFER_TOO_SMALL; + } + if (stat (FileName == NULL ? PrivateFile->FileName : FileName, &buf) < 0) { + return EFI_DEVICE_ERROR; + } + + Status = EFI_SUCCESS; + + Info = Buffer; + ZeroMem (Info, ResultSize); + + Info->Size = ResultSize; + Info->FileSize = buf.st_size; + Info->PhysicalSize = MultU64x32 (buf.st_blocks, buf.st_blksize); + + PosixSystemTimeToEfiTime (buf.st_ctime, &Info->CreateTime); + PosixSystemTimeToEfiTime (buf.st_atime, &Info->LastAccessTime); + PosixSystemTimeToEfiTime (buf.st_mtime, &Info->ModificationTime); + + if (!(buf.st_mode & S_IWUSR)) { + Info->Attribute |= EFI_FILE_READ_ONLY; + } + + if (S_ISDIR(buf.st_mode)) { + Info->Attribute |= EFI_FILE_DIRECTORY; + } + + + BufferFileName = (CHAR16 *)((CHAR8 *) Buffer + Size); + while (*RealFileName) { + *BufferFileName++ = *RealFileName++; + } + *BufferFileName = 0; + + *BufferSize = ResultSize; + return Status; +} + +BOOLEAN +IsZero ( + IN VOID *Buffer, + IN UINTN Length + ) +{ + if (Buffer == NULL || Length == 0) { + return FALSE; + } + + if (*(UINT8 *) Buffer != 0) { + return FALSE; + } + + if (Length > 1) { + if (!CompareMem (Buffer, (UINT8 *) Buffer + 1, Length - 1)) { + return FALSE; + } + } + + return TRUE; +} + + + +/** + 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 +PosixFileOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + EFI_FILE_PROTOCOL *Root; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EMU_EFI_FILE_PRIVATE *NewPrivateFile; + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot; + EFI_STATUS Status; + CHAR16 *Src; + char *Dst; + CHAR8 *RealFileName; + char *ParseFileName; + char *GuardPointer; + CHAR8 TempChar; + UINTN Count; + BOOLEAN TrailingDash; + BOOLEAN LoopFinish; + UINTN InfoSize; + EFI_FILE_INFO *Info; + struct stat finfo; + int res; + UINTN Size; + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + PrivateRoot = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem); + NewPrivateFile = NULL; + Status = EFI_OUT_OF_RESOURCES; + + // + // BUGBUG: assume an open of root + // if current location, return current data + // + TrailingDash = FALSE; + if ((StrCmp (FileName, L"\\") == 0) || + (StrCmp (FileName, L".") == 0 && PrivateFile->IsRootDirectory)) { +OpenRoot: + Status = PosixOpenVolume (PrivateFile->SimpleFileSystem, &Root); + NewPrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (Root); + goto Done; + } + + if (FileName[StrLen (FileName) - 1] == L'\\') { + TrailingDash = TRUE; + FileName[StrLen (FileName) - 1] = 0; + } + + // + // Attempt to open the file + // + NewPrivateFile = malloc (sizeof (EMU_EFI_FILE_PRIVATE)); + if (NewPrivateFile == NULL) { + goto Done; + } + + CopyMem (NewPrivateFile, PrivateFile, sizeof (EMU_EFI_FILE_PRIVATE)); + + Size = AsciiStrSize (PrivateFile->FileName) + 1 + StrLen (FileName) + 1; + NewPrivateFile->FileName = malloc (Size); + if (NewPrivateFile->FileName == NULL) { + goto Done; + } + + if (*FileName == L'\\') { + AsciiStrCpyS (NewPrivateFile->FileName, Size, PrivateRoot->FilePath); + // Skip first '\'. + Src = FileName + 1; + } else { + AsciiStrCpyS (NewPrivateFile->FileName, Size, PrivateFile->FileName); + Src = FileName; + } + Dst = NewPrivateFile->FileName + AsciiStrLen (NewPrivateFile->FileName); + GuardPointer = NewPrivateFile->FileName + AsciiStrLen (PrivateRoot->FilePath); + *Dst++ = '/'; + // Convert unicode to ascii and '\' to '/' + while (*Src) { + if (*Src == '\\') { + *Dst++ = '/'; + } else { + *Dst++ = *Src; + } + Src++; + } + *Dst = 0; + + + // + // Get rid of . and .., except leading . or .. + // + + // + // GuardPointer protect simplefilesystem root path not be destroyed + // + + LoopFinish = FALSE; + while (!LoopFinish) { + LoopFinish = TRUE; + + for (ParseFileName = GuardPointer; *ParseFileName; ParseFileName++) { + if (*ParseFileName == '.' && + (*(ParseFileName + 1) == 0 || *(ParseFileName + 1) == '/') && + *(ParseFileName - 1) == '/' + ) { + + // + // cut /. + // + CutPrefix (ParseFileName - 1, 2); + LoopFinish = FALSE; + break; + } + + if (*ParseFileName == '.' && + *(ParseFileName + 1) == '.' && + (*(ParseFileName + 2) == 0 || *(ParseFileName + 2) == '/') && + *(ParseFileName - 1) == '/' + ) { + + ParseFileName--; + Count = 3; + + while (ParseFileName != GuardPointer) { + ParseFileName--; + Count++; + if (*ParseFileName == '/') { + break; + } + } + + // + // cut /.. and its left directory + // + CutPrefix (ParseFileName, Count); + LoopFinish = FALSE; + break; + } + } + } + + if (AsciiStrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) { + NewPrivateFile->IsRootDirectory = TRUE; + free (NewPrivateFile->FileName); + free (NewPrivateFile); + goto OpenRoot; + } + + RealFileName = NewPrivateFile->FileName + AsciiStrLen(NewPrivateFile->FileName) - 1; + while (RealFileName > NewPrivateFile->FileName && *RealFileName != '/') { + RealFileName--; + } + + TempChar = *(RealFileName - 1); + *(RealFileName - 1) = 0; + *(RealFileName - 1) = TempChar; + + + // + // Test whether file or directory + // + NewPrivateFile->IsRootDirectory = FALSE; + NewPrivateFile->fd = -1; + NewPrivateFile->Dir = NULL; + if (OpenMode & EFI_FILE_MODE_CREATE) { + if (Attributes & EFI_FILE_DIRECTORY) { + NewPrivateFile->IsDirectoryPath = TRUE; + } else { + NewPrivateFile->IsDirectoryPath = FALSE; + } + } else { + res = stat (NewPrivateFile->FileName, &finfo); + if (res == 0 && S_ISDIR(finfo.st_mode)) { + NewPrivateFile->IsDirectoryPath = TRUE; + } else { + NewPrivateFile->IsDirectoryPath = FALSE; + } + } + + if (OpenMode & EFI_FILE_MODE_WRITE) { + NewPrivateFile->IsOpenedByRead = FALSE; + } else { + NewPrivateFile->IsOpenedByRead = TRUE; + } + + Status = EFI_SUCCESS; + + // + // deal with directory + // + if (NewPrivateFile->IsDirectoryPath) { + if ((OpenMode & EFI_FILE_MODE_CREATE)) { + // + // Create a directory + // + if (mkdir (NewPrivateFile->FileName, 0777) != 0) { + if (errno != EEXIST) { + //free (TempFileName); + Status = EFI_ACCESS_DENIED; + goto Done; + } + } + } + + NewPrivateFile->Dir = opendir (NewPrivateFile->FileName); + if (NewPrivateFile->Dir == NULL) { + if (errno == EACCES) { + Status = EFI_ACCESS_DENIED; + } else { + Status = EFI_NOT_FOUND; + } + + goto Done; + } + + } else { + // + // deal with file + // + NewPrivateFile->fd = open ( + NewPrivateFile->FileName, + ((OpenMode & EFI_FILE_MODE_CREATE) ? O_CREAT : 0) | (NewPrivateFile->IsOpenedByRead ? O_RDONLY : O_RDWR), + 0666 + ); + if (NewPrivateFile->fd < 0) { + if (errno == ENOENT) { + Status = EFI_NOT_FOUND; + } else { + Status = EFI_ACCESS_DENIED; + } + } + } + + if ((OpenMode & EFI_FILE_MODE_CREATE) && Status == EFI_SUCCESS) { + // + // Set the attribute + // + InfoSize = 0; + Info = NULL; + Status = PosixFileGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info); + if (Status != EFI_BUFFER_TOO_SMALL) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + Info = malloc (InfoSize); + if (Info == NULL) { + goto Done; + } + + Status = PosixFileGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info); + if (EFI_ERROR (Status)) { + goto Done; + } + + Info->Attribute = Attributes; + PosixFileSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info); + + free (Info); + } + +Done: ; + if (TrailingDash) { + FileName[StrLen (FileName) + 1] = 0; + FileName[StrLen (FileName)] = L'\\'; + } + + if (EFI_ERROR (Status)) { + if (NewPrivateFile) { + if (NewPrivateFile->FileName) { + free (NewPrivateFile->FileName); + } + + free (NewPrivateFile); + } + } else { + *NewHandle = &NewPrivateFile->EfiFile; + } + + return Status; +} + + + +/** + Close the file handle + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The device was opened. + +**/ +EFI_STATUS +PosixFileCLose ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EMU_EFI_FILE_PRIVATE *PrivateFile; + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->fd >= 0) { + close (PrivateFile->fd); + } + if (PrivateFile->Dir != NULL) { + closedir (PrivateFile->Dir); + } + + PrivateFile->fd = -1; + PrivateFile->Dir = NULL; + + if (PrivateFile->FileName) { + free (PrivateFile->FileName); + } + + free (PrivateFile); + + return EFI_SUCCESS; +} + + +/** + Close and delete the file handle. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The device was opened. + @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted. + +**/ +EFI_STATUS +PosixFileDelete ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + Status = EFI_WARN_DELETE_FAILURE; + + if (PrivateFile->IsDirectoryPath) { + if (PrivateFile->Dir != NULL) { + closedir (PrivateFile->Dir); + PrivateFile->Dir = NULL; + } + + if (rmdir (PrivateFile->FileName) == 0) { + Status = EFI_SUCCESS; + } + } else { + close (PrivateFile->fd); + PrivateFile->fd = -1; + + if (!PrivateFile->IsOpenedByRead) { + if (!unlink (PrivateFile->FileName)) { + Status = EFI_SUCCESS; + } + } + } + + free (PrivateFile->FileName); + free (PrivateFile); + + 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 +PosixFileRead ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_STATUS Status; + int Res; + UINTN Size; + UINTN NameSize; + UINTN ResultSize; + CHAR8 *FullFileName; + UINTN FullFileNameSize; + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (!PrivateFile->IsDirectoryPath) { + if (PrivateFile->fd < 0) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + Res = read (PrivateFile->fd, Buffer, *BufferSize); + if (Res < 0) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + *BufferSize = Res; + Status = EFI_SUCCESS; + goto Done; + } + + // + // Read on a directory. + // + if (PrivateFile->Dir == NULL) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + if (PrivateFile->Dirent == NULL) { + PrivateFile->Dirent = readdir (PrivateFile->Dir); + if (PrivateFile->Dirent == NULL) { + *BufferSize = 0; + Status = EFI_SUCCESS; + goto Done; + } + } + + Size = SIZE_OF_EFI_FILE_INFO; + NameSize = AsciiStrLen (PrivateFile->Dirent->d_name) + 1; + ResultSize = Size + 2 * NameSize; + + if (*BufferSize < ResultSize) { + *BufferSize = ResultSize; + Status = EFI_BUFFER_TOO_SMALL; + goto Done; + } + Status = EFI_SUCCESS; + + *BufferSize = ResultSize; + + FullFileNameSize = AsciiStrLen(PrivateFile->FileName) + 1 + NameSize; + FullFileName = malloc (FullFileNameSize); + if (FullFileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + AsciiStrCpyS (FullFileName, FullFileNameSize, PrivateFile->FileName); + AsciiStrCatS (FullFileName, FullFileNameSize, "/"); + AsciiStrCatS (FullFileName, FullFileNameSize, PrivateFile->Dirent->d_name); + Status = UnixSimpleFileSystemFileInfo ( + PrivateFile, + FullFileName, + BufferSize, + Buffer + ); + free (FullFileName); + + PrivateFile->Dirent = NULL; + +Done: + 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 +PosixFileWrite ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +{ + EMU_EFI_FILE_PRIVATE *PrivateFile; + int Res; + + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->fd < 0) { + return EFI_DEVICE_ERROR; + } + + if (PrivateFile->IsDirectoryPath) { + return EFI_UNSUPPORTED; + } + + if (PrivateFile->IsOpenedByRead) { + return EFI_ACCESS_DENIED; + } + + Res = write (PrivateFile->fd, Buffer, *BufferSize); + if (Res == (UINTN)-1) { + return ErrnoToEfiStatus (); + } + + *BufferSize = Res; + return EFI_SUCCESS; +} + + + +/** + Set a files current position + + @param This Protocol instance pointer. + @param Position Byte position from the start of the file. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open. + +**/ +EFI_STATUS +PosixFileSetPossition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ) +{ + EMU_EFI_FILE_PRIVATE *PrivateFile; + off_t Pos; + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->IsDirectoryPath) { + if (Position != 0) { + return EFI_UNSUPPORTED; + } + + if (PrivateFile->Dir == NULL) { + return EFI_DEVICE_ERROR; + } + rewinddir (PrivateFile->Dir); + return EFI_SUCCESS; + } else { + if (Position == (UINT64) -1) { + Pos = lseek (PrivateFile->fd, 0, SEEK_END); + } else { + Pos = lseek (PrivateFile->fd, Position, SEEK_SET); + } + if (Pos == (off_t)-1) { + return ErrnoToEfiStatus (); + } + return EFI_SUCCESS; + } +} + + + +/** + Get a file's current position + + @param This Protocol instance pointer. + @param Position Byte position from the start of the file. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.. + +**/ +EFI_STATUS +PosixFileGetPossition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ) +{ + EFI_STATUS Status; + EMU_EFI_FILE_PRIVATE *PrivateFile; + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->IsDirectoryPath) { + Status = EFI_UNSUPPORTED; + } else { + *Position = (UINT64)lseek (PrivateFile->fd, 0, SEEK_CUR); + Status = (*Position == (UINT64) -1) ? ErrnoToEfiStatus () : EFI_SUCCESS; + } + + 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 +PosixFileGetInfo ( + 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_FILE_SYSTEM_INFO *FileSystemInfoBuffer; + int UnixStatus; + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot; + struct statfs buf; + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + PrivateRoot = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem); + + Status = EFI_SUCCESS; + if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { + Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, BufferSize, Buffer); + } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { + if (*BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) { + *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); + return EFI_BUFFER_TOO_SMALL; + } + + UnixStatus = statfs (PrivateFile->FileName, &buf); + if (UnixStatus < 0) { + return EFI_DEVICE_ERROR; + } + + FileSystemInfoBuffer = (EFI_FILE_SYSTEM_INFO *) Buffer; + FileSystemInfoBuffer->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); + FileSystemInfoBuffer->ReadOnly = FALSE; + + // + // Succeeded + // + FileSystemInfoBuffer->VolumeSize = MultU64x32 (buf.f_blocks, buf.f_bsize); + FileSystemInfoBuffer->FreeSpace = MultU64x32 (buf.f_bavail, buf.f_bsize); + FileSystemInfoBuffer->BlockSize = buf.f_bsize; + + + StrCpyS ( + (CHAR16 *) FileSystemInfoBuffer->VolumeLabel, + (*BufferSize - SIZE_OF_EFI_FILE_SYSTEM_INFO) / sizeof (CHAR16), + PrivateRoot->VolumeLabel + ); + *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); + + } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { + if (*BufferSize < StrSize (PrivateRoot->VolumeLabel)) { + *BufferSize = StrSize (PrivateRoot->VolumeLabel); + return EFI_BUFFER_TOO_SMALL; + } + + StrCpyS ( + (CHAR16 *) Buffer, + *BufferSize / sizeof (CHAR16), + PrivateRoot->VolumeLabel + ); + *BufferSize = StrSize (PrivateRoot->VolumeLabel); + + } + + 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 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. + +**/ +EFI_STATUS +PosixFileSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot; + EMU_EFI_FILE_PRIVATE *PrivateFile; + EFI_FILE_INFO *OldFileInfo; + EFI_FILE_INFO *NewFileInfo; + EFI_STATUS Status; + UINTN OldInfoSize; + mode_t NewAttr; + struct stat OldAttr; + CHAR8 *OldFileName; + CHAR8 *NewFileName; + CHAR8 *CharPointer; + BOOLEAN AttrChangeFlag; + BOOLEAN NameChangeFlag; + BOOLEAN SizeChangeFlag; + BOOLEAN TimeChangeFlag; + struct tm NewLastAccessSystemTime; + struct tm NewLastWriteSystemTime; + EFI_FILE_SYSTEM_INFO *NewFileSystemInfo; + CHAR8 *AsciiFilePtr; + CHAR16 *UnicodeFilePtr; + int UnixStatus; + struct utimbuf Utime; + UINTN Size; + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + PrivateRoot = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem); + errno = 0; + Status = EFI_UNSUPPORTED; + OldFileInfo = NewFileInfo = NULL; + OldFileName = NewFileName = NULL; + AttrChangeFlag = NameChangeFlag = SizeChangeFlag = TimeChangeFlag = FALSE; + + // + // Set file system information. + // + if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { + if (BufferSize < (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel))) { + Status = EFI_BAD_BUFFER_SIZE; + goto Done; + } + + NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *) Buffer; + + free (PrivateRoot->VolumeLabel); + + PrivateRoot->VolumeLabel = malloc (StrSize (NewFileSystemInfo->VolumeLabel)); + if (PrivateRoot->VolumeLabel == NULL) { + goto Done; + } + + StrCpyS ( + PrivateRoot->VolumeLabel, + StrSize (NewFileSystemInfo->VolumeLabel) / sizeof (CHAR16), + NewFileSystemInfo->VolumeLabel + ); + + Status = EFI_SUCCESS; + goto Done; + } + + // + // Set volume label information. + // + if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { + if (BufferSize < StrSize (PrivateRoot->VolumeLabel)) { + Status = EFI_BAD_BUFFER_SIZE; + goto Done; + } + + StrCpyS ( + PrivateRoot->VolumeLabel, + StrSize (PrivateRoot->VolumeLabel) / sizeof (CHAR16), + (CHAR16 *) Buffer + ); + + Status = EFI_SUCCESS; + goto Done; + } + + if (!CompareGuid (InformationType, &gEfiFileInfoGuid)) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + if (BufferSize < SIZE_OF_EFI_FILE_INFO) { + Status = EFI_BAD_BUFFER_SIZE; + goto Done; + } + + // + // Set file/directory information. + // + + // + // Check for invalid set file information parameters. + // + NewFileInfo = (EFI_FILE_INFO *) Buffer; + if (NewFileInfo->Size <= sizeof (EFI_FILE_INFO) || + (NewFileInfo->Attribute &~(EFI_FILE_VALID_ATTR)) || + (sizeof (UINTN) == 4 && NewFileInfo->Size > 0xFFFFFFFF) + ) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + // + // Get current file information so we can determine what kind + // of change request this is. + // + OldInfoSize = 0; + Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, &OldInfoSize, NULL); + if (Status != EFI_BUFFER_TOO_SMALL) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + OldFileInfo = malloc (OldInfoSize); + if (OldFileInfo == NULL) { + goto Done; + } + + Status = UnixSimpleFileSystemFileInfo (PrivateFile, NULL, &OldInfoSize, OldFileInfo); + if (EFI_ERROR (Status)) { + goto Done; + } + + OldFileName = malloc (AsciiStrSize (PrivateFile->FileName)); + if (OldFileInfo == NULL) { + goto Done; + } + + AsciiStrCpyS ( + OldFileName, + AsciiStrSize (PrivateFile->FileName), + PrivateFile->FileName + ); + + // + // Make full pathname from new filename and rootpath. + // + if (NewFileInfo->FileName[0] == '\\') { + Size = AsciiStrLen (PrivateRoot->FilePath) + 1 + StrLen (NewFileInfo->FileName) + 1; + NewFileName = malloc (Size); + if (NewFileName == NULL) { + goto Done; + } + + AsciiStrCpyS (NewFileName, Size, PrivateRoot->FilePath); + AsciiFilePtr = NewFileName + AsciiStrLen(NewFileName); + UnicodeFilePtr = NewFileInfo->FileName + 1; + *AsciiFilePtr++ ='/'; + } else { + Size = AsciiStrLen (PrivateFile->FileName) + 2 + StrLen (NewFileInfo->FileName) + 1; + NewFileName = malloc (Size); + if (NewFileName == NULL) { + goto Done; + } + + AsciiStrCpyS (NewFileName, Size, PrivateRoot->FilePath); + AsciiFilePtr = NewFileName + AsciiStrLen(NewFileName); + if ((AsciiFilePtr[-1] != '/') && (NewFileInfo->FileName[0] != '/')) { + // make sure there is a / between Root FilePath and NewFileInfo Filename + AsciiFilePtr[0] = '/'; + AsciiFilePtr[1] = '\0'; + AsciiFilePtr++; + } + UnicodeFilePtr = NewFileInfo->FileName; + } + // Convert to ascii. + while (*UnicodeFilePtr) { + *AsciiFilePtr++ = *UnicodeFilePtr++; + } + *AsciiFilePtr = 0; + + // + // Is there an attribute change request? + // + if (NewFileInfo->Attribute != OldFileInfo->Attribute) { + if ((NewFileInfo->Attribute & EFI_FILE_DIRECTORY) != (OldFileInfo->Attribute & EFI_FILE_DIRECTORY)) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + AttrChangeFlag = TRUE; + } + + // + // Is there a name change request? + // bugbug: - Should really use EFI_UNICODE_COLLATION_PROTOCOL + // + if (StrCmp (NewFileInfo->FileName, OldFileInfo->FileName)) { + NameChangeFlag = TRUE; + } + + // + // Is there a size change request? + // + if (NewFileInfo->FileSize != OldFileInfo->FileSize) { + SizeChangeFlag = TRUE; + } + + // + // Is there a time stamp change request? + // + if (!IsZero (&NewFileInfo->CreateTime, sizeof (EFI_TIME)) && + CompareMem (&NewFileInfo->CreateTime, &OldFileInfo->CreateTime, sizeof (EFI_TIME)) + ) { + TimeChangeFlag = TRUE; + } else if (!IsZero (&NewFileInfo->LastAccessTime, sizeof (EFI_TIME)) && + CompareMem (&NewFileInfo->LastAccessTime, &OldFileInfo->LastAccessTime, sizeof (EFI_TIME)) + ) { + TimeChangeFlag = TRUE; + } else if (!IsZero (&NewFileInfo->ModificationTime, sizeof (EFI_TIME)) && + CompareMem (&NewFileInfo->ModificationTime, &OldFileInfo->ModificationTime, sizeof (EFI_TIME)) + ) { + TimeChangeFlag = TRUE; + } + + // + // All done if there are no change requests being made. + // + if (!(AttrChangeFlag || NameChangeFlag || SizeChangeFlag || TimeChangeFlag)) { + Status = EFI_SUCCESS; + goto Done; + } + + // + // Set file or directory information. + // + if (stat (OldFileName, &OldAttr) != 0) { + Status = ErrnoToEfiStatus (); + goto Done; + } + + // + // Name change. + // + if (NameChangeFlag) { + // + // Close the handles first + // + if (PrivateFile->IsOpenedByRead) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + for (CharPointer = NewFileName; *CharPointer != 0 && *CharPointer != L'/'; CharPointer++) { + } + + if (*CharPointer != 0) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + UnixStatus = rename (OldFileName, NewFileName); + if (UnixStatus == 0) { + // + // modify file name + // + free (PrivateFile->FileName); + + PrivateFile->FileName = malloc (AsciiStrSize (NewFileName)); + if (PrivateFile->FileName == NULL) { + goto Done; + } + + AsciiStrCpyS ( + PrivateFile->FileName, + AsciiStrSize (NewFileName), + NewFileName + ); + } else { + Status = EFI_DEVICE_ERROR; + goto Done; + } + } + + // + // Size change + // + if (SizeChangeFlag) { + if (PrivateFile->IsDirectoryPath) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + if (PrivateFile->IsOpenedByRead || OldFileInfo->Attribute & EFI_FILE_READ_ONLY) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + if (ftruncate (PrivateFile->fd, NewFileInfo->FileSize) != 0) { + Status = ErrnoToEfiStatus (); + goto Done; + } + + } + + // + // Time change + // + if (TimeChangeFlag) { + NewLastAccessSystemTime.tm_year = NewFileInfo->LastAccessTime.Year; + NewLastAccessSystemTime.tm_mon = NewFileInfo->LastAccessTime.Month; + NewLastAccessSystemTime.tm_mday = NewFileInfo->LastAccessTime.Day; + NewLastAccessSystemTime.tm_hour = NewFileInfo->LastAccessTime.Hour; + NewLastAccessSystemTime.tm_min = NewFileInfo->LastAccessTime.Minute; + NewLastAccessSystemTime.tm_sec = NewFileInfo->LastAccessTime.Second; + NewLastAccessSystemTime.tm_isdst = 0; + + Utime.actime = mktime (&NewLastAccessSystemTime); + + NewLastWriteSystemTime.tm_year = NewFileInfo->ModificationTime.Year; + NewLastWriteSystemTime.tm_mon = NewFileInfo->ModificationTime.Month; + NewLastWriteSystemTime.tm_mday = NewFileInfo->ModificationTime.Day; + NewLastWriteSystemTime.tm_hour = NewFileInfo->ModificationTime.Hour; + NewLastWriteSystemTime.tm_min = NewFileInfo->ModificationTime.Minute; + NewLastWriteSystemTime.tm_sec = NewFileInfo->ModificationTime.Second; + NewLastWriteSystemTime.tm_isdst = 0; + + Utime.modtime = mktime (&NewLastWriteSystemTime); + + if (Utime.actime == (time_t)-1 || Utime.modtime == (time_t)-1) { + goto Done; + } + + if (utime (PrivateFile->FileName, &Utime) == -1) { + Status = ErrnoToEfiStatus (); + goto Done; + } + } + + // + // No matter about AttrChangeFlag, Attribute must be set. + // Because operation before may cause attribute change. + // + NewAttr = OldAttr.st_mode; + + if (NewFileInfo->Attribute & EFI_FILE_READ_ONLY) { + NewAttr &= ~(S_IRUSR | S_IRGRP | S_IROTH); + } else { + NewAttr |= S_IRUSR; + } + + if (chmod (NewFileName, NewAttr) != 0) { + Status = ErrnoToEfiStatus (); + } + +Done: + if (OldFileInfo != NULL) { + free (OldFileInfo); + } + + if (OldFileName != NULL) { + free (OldFileName); + } + + if (NewFileName != NULL) { + free (NewFileName); + } + + return Status; +} + + +/** + Flush data back for the file handle. + + @param This Protocol instance pointer. + + @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_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 +PosixFileFlush ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EMU_EFI_FILE_PRIVATE *PrivateFile; + + + PrivateFile = EMU_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->IsDirectoryPath) { + return EFI_UNSUPPORTED; + } + + if (PrivateFile->IsOpenedByRead) { + return EFI_ACCESS_DENIED; + } + + if (PrivateFile->fd < 0) { + return EFI_DEVICE_ERROR; + } + + if (fsync (PrivateFile->fd) != 0) { + return ErrnoToEfiStatus (); + } + + return EFI_SUCCESS; +} + + + +EFI_STATUS +PosixFileSystmeThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + UINTN i; + + if (This->Private != NULL) { + return EFI_ALREADY_STARTED; + } + + if (!CompareGuid (This->Protocol, &gEfiSimpleFileSystemProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + Private = malloc (sizeof (EMU_SIMPLE_FILE_SYSTEM_PRIVATE)); + if (Private == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Private->FilePath = malloc (StrLen (This->ConfigString) + 1); + if (Private->FilePath == NULL) { + free (Private); + return EFI_OUT_OF_RESOURCES; + } + + // Convert Unicode to Ascii + for (i = 0; This->ConfigString[i] != 0; i++) { + Private->FilePath[i] = This->ConfigString[i]; + } + Private->FilePath[i] = 0; + + + Private->VolumeLabel = malloc (StrSize (L"EFI_EMULATED")); + if (Private->VolumeLabel == NULL) { + free (Private->FilePath); + free (Private); + return EFI_OUT_OF_RESOURCES; + } + StrCpyS ( + Private->VolumeLabel, + StrSize (L"EFI_EMULATED") / sizeof (CHAR16), + L"EFI_EMULATED" + ); + + Private->Signature = EMU_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE; + Private->Thunk = This; + CopyMem (&Private->SimpleFileSystem, &gPosixFileSystemProtocol, sizeof (Private->SimpleFileSystem)); + Private->FileHandlesOpen = FALSE; + + This->Interface = &Private->SimpleFileSystem; + This->Private = Private; + return EFI_SUCCESS; +} + + +EFI_STATUS +PosixFileSystmeThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + EMU_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + + if (!CompareGuid (This->Protocol, &gEfiSimpleFileSystemProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + Private = This->Private; + + if (Private->FileHandlesOpen) { + // + // Close only supported if all the EFI_FILE_HANDLEs have been closed. + // + return EFI_NOT_READY; + } + + if (This->Private != NULL) { + if (Private->VolumeLabel != NULL) { + free (Private->VolumeLabel); + } + free (This->Private); + This->Private = NULL; + } + + return EFI_SUCCESS; +} + + +EMU_IO_THUNK_PROTOCOL gPosixFileSystemThunkIo = { + &gEfiSimpleFileSystemProtocolGuid, + NULL, + NULL, + 0, + GasketPosixFileSystmeThunkOpen, + GasketPosixFileSystmeThunkClose, + NULL +}; + + diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/Pthreads.c b/CdeEmuPkg/EmulatorPkg/Unix/Host/Pthreads.c new file mode 100644 index 00000000000..3d6c5200948 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/Pthreads.c @@ -0,0 +1,229 @@ +/*++ @file + POSIX Pthreads to emulate APs and implement threads + +Copyright (c) 2011, Apple Inc. All rights reserved. +Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + + +**/ + +#include "Host.h" +#include + + +UINTN +EFIAPI +PthreadMutexLock ( + IN VOID *Mutex + ) +{ + return (UINTN)pthread_mutex_lock ((pthread_mutex_t *)Mutex); +} + + + +UINTN +EFIAPI +PthreadMutexUnLock ( + IN VOID *Mutex + ) +{ + return (UINTN)pthread_mutex_unlock ((pthread_mutex_t *)Mutex); +} + + +UINTN +EFIAPI +PthreadMutexTryLock ( + IN VOID *Mutex + ) +{ + return (UINTN)pthread_mutex_trylock ((pthread_mutex_t *)Mutex); +} + + +VOID * +PthreadMutexInit ( + IN VOID + ) +{ + pthread_mutex_t *Mutex; + int err; + + Mutex = malloc (sizeof (pthread_mutex_t)); + err = pthread_mutex_init (Mutex, NULL); + if (err == 0) { + return Mutex; + } + + return NULL; +} + + +UINTN +PthreadMutexDestroy ( + IN VOID *Mutex + ) +{ + if (Mutex != NULL) { + return pthread_mutex_destroy ((pthread_mutex_t *)Mutex); + } + + return -1; +} + +// Can't store this data on PthreadCreate stack so we need a global +typedef struct { + pthread_mutex_t Mutex; + THREAD_THUNK_THREAD_ENTRY Start; +} THREAD_MANGLE; + +THREAD_MANGLE mThreadMangle = { + PTHREAD_MUTEX_INITIALIZER, + NULL +}; + +VOID * +SecFakePthreadStart ( + VOID *Context + ) +{ + THREAD_THUNK_THREAD_ENTRY Start; + sigset_t SigMask; + + // Save global on the stack before we unlock + Start = mThreadMangle.Start; + pthread_mutex_unlock (&mThreadMangle.Mutex); + + // Mask all signals to the APs + sigfillset (&SigMask); + pthread_sigmask (SIG_BLOCK, &SigMask, NULL); + + // + // We have to start the thread in SEC as we need to follow + // OS X calling conventions. We can then call back into + // to the callers Start. + // + // This is a great example of how all problems in computer + // science can be solved by adding another level of indirection + // + return (VOID *)ReverseGasketUint64 ((UINTN)Start, (UINTN)Context); +} + +UINTN +PthreadCreate ( + IN VOID *Thread, + IN VOID *Attribute, + IN THREAD_THUNK_THREAD_ENTRY Start, + IN VOID *Context + ) +{ + int err; + BOOLEAN EnabledOnEntry; + + // + // Threads inherit interrupt state so disable interrupts before we start thread + // + if (SecInterruptEanbled ()) { + SecDisableInterrupt (); + EnabledOnEntry = TRUE; + } else { + EnabledOnEntry = FALSE; + } + + // Acquire lock for global, SecFakePthreadStart runs in a different thread. + pthread_mutex_lock (&mThreadMangle.Mutex); + mThreadMangle.Start = Start; + + err = pthread_create (Thread, Attribute, SecFakePthreadStart, Context); + if (err != 0) { + // Thread failed to launch so release the lock; + pthread_mutex_unlock (&mThreadMangle.Mutex); + } + + if (EnabledOnEntry) { + // Restore interrupt state + SecEnableInterrupt (); + } + + return err; +} + + +VOID +PthreadExit ( + IN VOID *ValuePtr + ) +{ + pthread_exit (ValuePtr); + return; +} + + +UINTN +PthreadSelf ( + VOID + ) +{ + // POSIX currently allows pthread_t to be a structure or arithmetic type. + // Check out sys/types.h to make sure this will work if you are porting. + // On OS X (Darwin) pthread_t is a pointer to a structure so this code works. + return (UINTN)pthread_self (); +} + + +EMU_THREAD_THUNK_PROTOCOL gPthreadThunk = { + GasketPthreadMutexLock, + GasketPthreadMutexUnLock, + GasketPthreadMutexTryLock, + GasketPthreadMutexInit, + GasketPthreadMutexDestroy, + GasketPthreadCreate, + GasketPthreadExit, + GasketPthreadSelf +}; + + +EFI_STATUS +PthreadOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + if (This->Instance != 0) { + // Only single instance is supported + return EFI_NOT_FOUND; + } + + if (This->ConfigString[0] == L'0') { + // If AP count is zero no need for threads + return EFI_NOT_FOUND; + } + + This->Interface = &gPthreadThunk; + + return EFI_SUCCESS; +} + + +EFI_STATUS +PthreadClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + return EFI_SUCCESS; +} + + +EMU_IO_THUNK_PROTOCOL gPthreadThunkIo = { + &gEmuThreadThunkProtocolGuid, + NULL, + NULL, + 0, + GasketPthreadOpen, + GasketPthreadClose, + NULL +}; + + diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/X11GraphicsWindow.c b/CdeEmuPkg/EmulatorPkg/Unix/Host/X11GraphicsWindow.c new file mode 100644 index 00000000000..be297f51b4e --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/X11GraphicsWindow.c @@ -0,0 +1,1022 @@ +/*++ @file + +Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.
+Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Host.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define KEYSYM_LOWER 0 +#define KEYSYM_UPPER 1 + + +struct uga_drv_shift_mask { + unsigned char shift; + unsigned char size; + unsigned char csize; +}; + +#define NBR_KEYS 32 +typedef struct { + EMU_GRAPHICS_WINDOW_PROTOCOL GraphicsIo; + + Display *display; + int screen; // values for window_size in main + Window win; + GC gc; + Visual *visual; + + int depth; + unsigned int width; + unsigned int height; + unsigned int line_bytes; + unsigned int pixel_shift; + unsigned char *image_data; + + struct uga_drv_shift_mask r, g, b; + + int use_shm; + XShmSegmentInfo xshm_info; + XImage *image; + char *Title; + + unsigned int key_rd; + unsigned int key_wr; + unsigned int key_count; + EFI_KEY_DATA keys[NBR_KEYS]; + + EFI_KEY_STATE KeyState; + + EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeRegisterdKeyCallback; + EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakRegisterdKeyCallback; + VOID *RegisterdKeyCallbackContext; + + int previous_x; + int previous_y; + EFI_SIMPLE_POINTER_STATE pointer_state; + int pointer_state_changed; +} GRAPHICS_IO_PRIVATE; + +void +HandleEvents( + IN GRAPHICS_IO_PRIVATE *Drv + ); + +void +fill_shift_mask ( + IN struct uga_drv_shift_mask *sm, + IN unsigned long mask + ) +{ + sm->shift = 0; + sm->size = 0; + while ((mask & 1) == 0) { + mask >>= 1; + sm->shift++; + } + while (mask & 1) { + sm->size++; + mask >>= 1; + } + sm->csize = 8 - sm->size; +} + +int +TryCreateShmImage ( + IN GRAPHICS_IO_PRIVATE *Drv + ) +{ + Drv->image = XShmCreateImage ( + Drv->display, Drv->visual, + Drv->depth, ZPixmap, NULL, &Drv->xshm_info, + Drv->width, Drv->height + ); + if (Drv->image == NULL) { + return 0; + } + + switch (Drv->image->bitmap_unit) { + case 32: + Drv->pixel_shift = 2; + break; + case 16: + Drv->pixel_shift = 1; + break; + case 8: + Drv->pixel_shift = 0; + break; + } + + Drv->xshm_info.shmid = shmget ( + IPC_PRIVATE, Drv->image->bytes_per_line * Drv->image->height, + IPC_CREAT | 0777 + ); + if (Drv->xshm_info.shmid < 0) { + XDestroyImage(Drv->image); + return 0; + } + + Drv->image_data = shmat (Drv->xshm_info.shmid, NULL, 0); + if(!Drv->image_data) { + shmctl (Drv->xshm_info.shmid, IPC_RMID, NULL); + XDestroyImage(Drv->image); + return 0; + } + +#ifndef __APPLE__ + // + // This closes shared memory in real time on OS X. Only closes after folks quit using + // it on Linux. + // + shmctl (Drv->xshm_info.shmid, IPC_RMID, NULL); +#endif + + Drv->xshm_info.shmaddr = (char*)Drv->image_data; + Drv->image->data = (char*)Drv->image_data; + + if (!XShmAttach (Drv->display, &Drv->xshm_info)) { + shmdt (Drv->image_data); + XDestroyImage(Drv->image); + return 0; + } + return 1; +} + + +EFI_STATUS +X11Size ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN UINT32 Width, + IN UINT32 Height + ) +{ + GRAPHICS_IO_PRIVATE *Drv; + XSizeHints size_hints; + + // Destroy current buffer if created. + Drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + if (Drv->image != NULL) { + // Before destroy buffer, need to make sure the buffer available for access. + XDestroyImage (Drv->image); + + if (Drv->use_shm) { + shmdt (Drv->image_data); + } + + Drv->image_data = NULL; + Drv->image = NULL; + } + + Drv->width = Width; + Drv->height = Height; + XResizeWindow (Drv->display, Drv->win, Width, Height); + + // Allocate image. + if (XShmQueryExtension(Drv->display) && TryCreateShmImage(Drv)) { + Drv->use_shm = 1; + } else { + Drv->use_shm = 0; + if (Drv->depth > 16) { + Drv->pixel_shift = 2; + } else if (Drv->depth > 8) { + Drv->pixel_shift = 1; + } else { + Drv->pixel_shift = 0; + } + + Drv->image_data = malloc ((Drv->width * Drv->height) << Drv->pixel_shift); + Drv->image = XCreateImage ( + Drv->display, Drv->visual, Drv->depth, + ZPixmap, 0, (char *)Drv->image_data, + Drv->width, Drv->height, + 8 << Drv->pixel_shift, 0 + ); + } + + Drv->line_bytes = Drv->image->bytes_per_line; + + fill_shift_mask (&Drv->r, Drv->image->red_mask); + fill_shift_mask (&Drv->g, Drv->image->green_mask); + fill_shift_mask (&Drv->b, Drv->image->blue_mask); + + // Set WM hints. + size_hints.flags = PSize | PMinSize | PMaxSize; + size_hints.min_width = size_hints.max_width = size_hints.base_width = Width; + size_hints.min_height = size_hints.max_height = size_hints.base_height = Height; + XSetWMNormalHints (Drv->display, Drv->win, &size_hints); + + XMapWindow (Drv->display, Drv->win); + HandleEvents (Drv); + return EFI_SUCCESS; +} + +void +handleKeyEvent ( + IN GRAPHICS_IO_PRIVATE *Drv, + IN XEvent *ev, + IN BOOLEAN Make + ) +{ + KeySym *KeySym; + EFI_KEY_DATA KeyData; + int KeySymArraySize; + + if (Make) { + if (Drv->key_count == NBR_KEYS) { + return; + } + } + + // keycode is a physical key on the keyboard + // KeySym is a mapping of a physical key + // KeyboardMapping is the array of KeySym for a given keycode. key, shifted key, option key, command key, ... + // + // Returns an array of KeySymArraySize of KeySym for the keycode. [0] is lower case, [1] is upper case, + // [2] and [3] are based on option and command modifiers. The problem we have is command V + // could be mapped to a crazy Unicode character so the old scheme of returning a string. + // + KeySym = XGetKeyboardMapping (Drv->display, ev->xkey.keycode, 1, &KeySymArraySize); + + KeyData.Key.ScanCode = 0; + KeyData.Key.UnicodeChar = 0; + KeyData.KeyState.KeyShiftState = 0; + + // + // Skipping EFI_SCROLL_LOCK_ACTIVE & EFI_NUM_LOCK_ACTIVE since they are not on Macs + // + if ((ev->xkey.state & LockMask) == 0) { + Drv->KeyState.KeyToggleState &= ~EFI_CAPS_LOCK_ACTIVE; + } else { + if (Make) { + Drv->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE; + } + } + + // Skipping EFI_MENU_KEY_PRESSED and EFI_SYS_REQ_PRESSED + + switch (*KeySym) { + case XK_Control_R: + if (Make) { + Drv->KeyState.KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED; + } else { + Drv->KeyState.KeyShiftState &= ~EFI_RIGHT_CONTROL_PRESSED; + } + break; + case XK_Control_L: + if (Make) { + Drv->KeyState.KeyShiftState |= EFI_LEFT_CONTROL_PRESSED; + } else { + Drv->KeyState.KeyShiftState &= ~EFI_LEFT_CONTROL_PRESSED; + } + break; + + case XK_Shift_R: + if (Make) { + Drv->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED; + } else { + Drv->KeyState.KeyShiftState &= ~EFI_RIGHT_SHIFT_PRESSED; + } + break; + case XK_Shift_L: + if (Make) { + Drv->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED; + } else { + Drv->KeyState.KeyShiftState &= ~EFI_LEFT_SHIFT_PRESSED; + } + break; + + case XK_Mode_switch: + if (Make) { + Drv->KeyState.KeyShiftState |= EFI_LEFT_ALT_PRESSED; + } else { + Drv->KeyState.KeyShiftState &= ~EFI_LEFT_ALT_PRESSED; + } + break; + + case XK_Meta_R: + if (Make) { + Drv->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED; + } else { + Drv->KeyState.KeyShiftState &= ~EFI_RIGHT_LOGO_PRESSED; + } + break; + case XK_Meta_L: + if (Make) { + Drv->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED; + } else { + Drv->KeyState.KeyShiftState &= ~EFI_LEFT_LOGO_PRESSED; + } + break; + + case XK_KP_Home: + case XK_Home: KeyData.Key.ScanCode = SCAN_HOME; break; + + case XK_KP_End: + case XK_End: KeyData.Key.ScanCode = SCAN_END; break; + + case XK_KP_Left: + case XK_Left: KeyData.Key.ScanCode = SCAN_LEFT; break; + + case XK_KP_Right: + case XK_Right: KeyData.Key.ScanCode = SCAN_RIGHT; break; + + case XK_KP_Up: + case XK_Up: KeyData.Key.ScanCode = SCAN_UP; break; + + case XK_KP_Down: + case XK_Down: KeyData.Key.ScanCode = SCAN_DOWN; break; + + case XK_KP_Delete: + case XK_Delete: KeyData.Key.ScanCode = SCAN_DELETE; break; + + case XK_KP_Insert: + case XK_Insert: KeyData.Key.ScanCode = SCAN_INSERT; break; + + case XK_KP_Page_Up: + case XK_Page_Up: KeyData.Key.ScanCode = SCAN_PAGE_UP; break; + + case XK_KP_Page_Down: + case XK_Page_Down: KeyData.Key.ScanCode = SCAN_PAGE_DOWN; break; + + case XK_Escape: KeyData.Key.ScanCode = SCAN_ESC; break; + + case XK_Pause: KeyData.Key.ScanCode = SCAN_PAUSE; break; + + case XK_KP_F1: + case XK_F1: KeyData.Key.ScanCode = SCAN_F1; break; + + case XK_KP_F2: + case XK_F2: KeyData.Key.ScanCode = SCAN_F2; break; + + case XK_KP_F3: + case XK_F3: KeyData.Key.ScanCode = SCAN_F3; break; + + case XK_KP_F4: + case XK_F4: KeyData.Key.ScanCode = SCAN_F4; break; + + case XK_F5: KeyData.Key.ScanCode = SCAN_F5; break; + case XK_F6: KeyData.Key.ScanCode = SCAN_F6; break; + case XK_F7: KeyData.Key.ScanCode = SCAN_F7; break; + + // Don't map into X11 by default on a Mac + // System Preferences->Keyboard->Keyboard Shortcuts can be configured + // to not use higher function keys as shortcuts and the will show up + // in X11. + case XK_F8: KeyData.Key.ScanCode = SCAN_F8; break; + case XK_F9: KeyData.Key.ScanCode = SCAN_F9; break; + case XK_F10: KeyData.Key.ScanCode = SCAN_F10; break; + + case XK_F11: KeyData.Key.ScanCode = SCAN_F11; break; + case XK_F12: KeyData.Key.ScanCode = SCAN_F12; break; + + case XK_F13: KeyData.Key.ScanCode = SCAN_F13; break; + case XK_F14: KeyData.Key.ScanCode = SCAN_F14; break; + case XK_F15: KeyData.Key.ScanCode = SCAN_F15; break; + case XK_F16: KeyData.Key.ScanCode = SCAN_F16; break; + case XK_F17: KeyData.Key.ScanCode = SCAN_F17; break; + case XK_F18: KeyData.Key.ScanCode = SCAN_F18; break; + case XK_F19: KeyData.Key.ScanCode = SCAN_F19; break; + case XK_F20: KeyData.Key.ScanCode = SCAN_F20; break; + case XK_F21: KeyData.Key.ScanCode = SCAN_F21; break; + case XK_F22: KeyData.Key.ScanCode = SCAN_F22; break; + case XK_F23: KeyData.Key.ScanCode = SCAN_F23; break; + case XK_F24: KeyData.Key.ScanCode = SCAN_F24; break; + + // No mapping in X11 + //case XK_: KeyData.Key.ScanCode = SCAN_MUTE; break; + //case XK_: KeyData.Key.ScanCode = SCAN_VOLUME_UP; break; + //case XK_: KeyData.Key.ScanCode = SCAN_VOLUME_DOWN; break; + //case XK_: KeyData.Key.ScanCode = SCAN_BRIGHTNESS_UP; break; + //case XK_: KeyData.Key.ScanCode = SCAN_BRIGHTNESS_DOWN; break; + //case XK_: KeyData.Key.ScanCode = SCAN_SUSPEND; break; + //case XK_: KeyData.Key.ScanCode = SCAN_HIBERNATE; break; + //case XK_: KeyData.Key.ScanCode = SCAN_TOGGLE_DISPLAY; break; + //case XK_: KeyData.Key.ScanCode = SCAN_RECOVERY; break; + //case XK_: KeyData.Key.ScanCode = SCAN_EJECT; break; + + case XK_BackSpace: KeyData.Key.UnicodeChar = 0x0008; break; + + case XK_KP_Tab: + case XK_Tab: KeyData.Key.UnicodeChar = 0x0009; break; + + case XK_Linefeed: KeyData.Key.UnicodeChar = 0x000a; break; + + case XK_KP_Enter: + case XK_Return: KeyData.Key.UnicodeChar = 0x000d; break; + + case XK_KP_Equal : KeyData.Key.UnicodeChar = L'='; break; + case XK_KP_Multiply : KeyData.Key.UnicodeChar = L'*'; break; + case XK_KP_Add : KeyData.Key.UnicodeChar = L'+'; break; + case XK_KP_Separator : KeyData.Key.UnicodeChar = L'~'; break; + case XK_KP_Subtract : KeyData.Key.UnicodeChar = L'-'; break; + case XK_KP_Decimal : KeyData.Key.UnicodeChar = L'.'; break; + case XK_KP_Divide : KeyData.Key.UnicodeChar = L'/'; break; + + case XK_KP_0 : KeyData.Key.UnicodeChar = L'0'; break; + case XK_KP_1 : KeyData.Key.UnicodeChar = L'1'; break; + case XK_KP_2 : KeyData.Key.UnicodeChar = L'2'; break; + case XK_KP_3 : KeyData.Key.UnicodeChar = L'3'; break; + case XK_KP_4 : KeyData.Key.UnicodeChar = L'4'; break; + case XK_KP_5 : KeyData.Key.UnicodeChar = L'5'; break; + case XK_KP_6 : KeyData.Key.UnicodeChar = L'6'; break; + case XK_KP_7 : KeyData.Key.UnicodeChar = L'7'; break; + case XK_KP_8 : KeyData.Key.UnicodeChar = L'8'; break; + case XK_KP_9 : KeyData.Key.UnicodeChar = L'9'; break; + + default: + ; + } + + // The global state is our state + KeyData.KeyState.KeyShiftState = Drv->KeyState.KeyShiftState; + KeyData.KeyState.KeyToggleState = Drv->KeyState.KeyToggleState; + + if (*KeySym < XK_BackSpace) { + if (((Drv->KeyState.KeyShiftState & (EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED)) != 0) || + ((Drv->KeyState.KeyToggleState & EFI_CAPS_LOCK_ACTIVE) != 0) ) { + + KeyData.Key.UnicodeChar = (CHAR16)KeySym[KEYSYM_UPPER]; + + // Per UEFI spec since we converted the Unicode clear the shift bits we pass up + KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED); + } else { + KeyData.Key.UnicodeChar = (CHAR16)KeySym[KEYSYM_LOWER]; + } + } else { + // XK_BackSpace is the start of XK_MISCELLANY. These are the XK_? keys we process in this file + ; + } + + if (Make) { + memcpy (&Drv->keys[Drv->key_wr], &KeyData, sizeof (EFI_KEY_DATA)); + Drv->key_wr = (Drv->key_wr + 1) % NBR_KEYS; + Drv->key_count++; + if (Drv->MakeRegisterdKeyCallback != NULL) { + ReverseGasketUint64Uint64 (Drv->MakeRegisterdKeyCallback ,Drv->RegisterdKeyCallbackContext, &KeyData); + } + } else { + if (Drv->BreakRegisterdKeyCallback != NULL) { + ReverseGasketUint64Uint64 (Drv->BreakRegisterdKeyCallback ,Drv->RegisterdKeyCallbackContext, &KeyData); + } + } +} + + +void +handleMouseMoved( + IN GRAPHICS_IO_PRIVATE *Drv, + IN XEvent *ev + ) +{ + if (ev->xmotion.x != Drv->previous_x) { + Drv->pointer_state.RelativeMovementX += ( ev->xmotion.x - Drv->previous_x ); + Drv->previous_x = ev->xmotion.x; + Drv->pointer_state_changed = 1; + } + + if (ev->xmotion.y != Drv->previous_y) { + Drv->pointer_state.RelativeMovementY += ( ev->xmotion.y - Drv->previous_y ); + Drv->previous_y = ev->xmotion.y; + Drv->pointer_state_changed = 1; + } + + Drv->pointer_state.RelativeMovementZ = 0; +} + +void +handleMouseDown ( + IN GRAPHICS_IO_PRIVATE *Drv, + IN XEvent *ev, + IN BOOLEAN Pressed + ) +{ + if (ev->xbutton.button == Button1) { + Drv->pointer_state_changed = (Drv->pointer_state.LeftButton != Pressed); + Drv->pointer_state.LeftButton = Pressed; + } + if ( ev->xbutton.button == Button2 ) { + Drv->pointer_state_changed = (Drv->pointer_state.RightButton != Pressed); + Drv->pointer_state.RightButton = Pressed; + } +} + +void +Redraw ( + IN GRAPHICS_IO_PRIVATE *Drv, + IN UINTN X, + IN UINTN Y, + IN UINTN Width, + IN UINTN Height + ) +{ + if (Drv->use_shm) { + XShmPutImage ( + Drv->display, Drv->win, Drv->gc, Drv->image, X, Y, X, Y, Width, Height, False + ); + } else { + XPutImage ( + Drv->display, Drv->win, Drv->gc, Drv->image, X, Y, X, Y, Width, Height + ); + } + XFlush(Drv->display); +} + +void +HandleEvent(GRAPHICS_IO_PRIVATE *Drv, XEvent *ev) +{ + switch (ev->type) { + case Expose: + Redraw (Drv, ev->xexpose.x, ev->xexpose.y, + ev->xexpose.width, ev->xexpose.height); + break; + case GraphicsExpose: + Redraw (Drv, ev->xgraphicsexpose.x, ev->xgraphicsexpose.y, + ev->xgraphicsexpose.width, ev->xgraphicsexpose.height); + break; + case KeyPress: + handleKeyEvent (Drv, ev, TRUE); + break; + case KeyRelease: + handleKeyEvent (Drv, ev, FALSE); + break; + case MappingNotify: + XRefreshKeyboardMapping (&ev->xmapping); + break; + case MotionNotify: + handleMouseMoved (Drv, ev); + break; + case ButtonPress: + handleMouseDown (Drv, ev, TRUE); + break; + case ButtonRelease: + handleMouseDown (Drv, ev, FALSE); + break; +#if 0 + case DestroyNotify: + XCloseDisplay (Drv->display); + exit (1); + break; +#endif + case NoExpose: + default: + break; + } +} + +void +HandleEvents ( + IN GRAPHICS_IO_PRIVATE *Drv + ) +{ + XEvent ev; + + while (XPending (Drv->display) != 0) { + XNextEvent (Drv->display, &ev); + HandleEvent (Drv, &ev); + } +} + +unsigned long +X11PixelToColor ( + IN GRAPHICS_IO_PRIVATE *Drv, + IN EFI_UGA_PIXEL pixel + ) +{ + return ((pixel.Red >> Drv->r.csize) << Drv->r.shift) + | ((pixel.Green >> Drv->g.csize) << Drv->g.shift) + | ((pixel.Blue >> Drv->b.csize) << Drv->b.shift); +} + +EFI_UGA_PIXEL +X11ColorToPixel ( + IN GRAPHICS_IO_PRIVATE *Drv, + IN unsigned long val + ) +{ + EFI_UGA_PIXEL Pixel; + + memset (&Pixel, 0, sizeof (EFI_UGA_PIXEL)); + + // Truncation not an issue since X11 and EFI are both using 8 bits per color + Pixel.Red = (val >> Drv->r.shift) << Drv->r.csize; + Pixel.Green = (val >> Drv->g.shift) << Drv->g.csize; + Pixel.Blue = (val >> Drv->b.shift) << Drv->b.csize; + + return Pixel; +} + + +EFI_STATUS +X11CheckKey ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo + ) +{ + GRAPHICS_IO_PRIVATE *Drv; + + Drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + + HandleEvents (Drv); + + if (Drv->key_count != 0) { + return EFI_SUCCESS; + } + + return EFI_NOT_READY; +} + +EFI_STATUS +X11GetKey ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_KEY_DATA *KeyData + ) +{ + EFI_STATUS EfiStatus; + GRAPHICS_IO_PRIVATE *Drv; + + Drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + + EfiStatus = X11CheckKey (GraphicsIo); + if (EFI_ERROR (EfiStatus)) { + return EfiStatus; + } + + CopyMem (KeyData, &Drv->keys[Drv->key_rd], sizeof (EFI_KEY_DATA)); + Drv->key_rd = (Drv->key_rd + 1) % NBR_KEYS; + Drv->key_count--; + + return EFI_SUCCESS; +} + + +EFI_STATUS +X11KeySetState ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_KEY_TOGGLE_STATE *KeyToggleState + ) +{ + GRAPHICS_IO_PRIVATE *Drv; + + Drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + + if (*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) { + if ((Drv->KeyState.KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == 0) { + // + // We could create an XKeyEvent and send a XK_Caps_Lock to + // the UGA/GOP Window + // + } + } + + Drv->KeyState.KeyToggleState = *KeyToggleState; + return EFI_SUCCESS; +} + + +EFI_STATUS +X11RegisterKeyNotify ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeCallBack, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakCallBack, + IN VOID *Context + ) +{ + GRAPHICS_IO_PRIVATE *Drv; + + Drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + + Drv->MakeRegisterdKeyCallback = MakeCallBack; + Drv->BreakRegisterdKeyCallback = BreakCallBack; + Drv->RegisterdKeyCallbackContext = Context; + + return EFI_SUCCESS; +} + + +EFI_STATUS +X11Blt ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_UGA_PIXEL *BltBuffer OPTIONAL, + IN EFI_UGA_BLT_OPERATION BltOperation, + IN EMU_GRAPHICS_WINDOWS__BLT_ARGS *Args + ) +{ + GRAPHICS_IO_PRIVATE *Private; + UINTN DstY; + UINTN SrcY; + UINTN DstX; + UINTN SrcX; + UINTN Index; + EFI_UGA_PIXEL *Blt; + UINT8 *Dst; + UINT8 *Src; + UINTN Nbr; + unsigned long Color; + XEvent ev; + + Private = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + + + // + // Check bounds + // + if (BltOperation == EfiUgaVideoToBltBuffer + || BltOperation == EfiUgaVideoToVideo) { + // + // Source is Video. + // + if (Args->SourceY + Args->Height > Private->height) { + return EFI_INVALID_PARAMETER; + } + + if (Args->SourceX + Args->Width > Private->width) { + return EFI_INVALID_PARAMETER; + } + } + + if (BltOperation == EfiUgaBltBufferToVideo + || BltOperation == EfiUgaVideoToVideo + || BltOperation == EfiUgaVideoFill) { + // + // Destination is Video + // + if (Args->DestinationY + Args->Height > Private->height) { + return EFI_INVALID_PARAMETER; + } + + if (Args->DestinationX + Args->Width > Private->width) { + return EFI_INVALID_PARAMETER; + } + } + + switch (BltOperation) { + case EfiUgaVideoToBltBuffer: + Blt = (EFI_UGA_PIXEL *)((UINT8 *)BltBuffer + (Args->DestinationY * Args->Delta) + Args->DestinationX * sizeof (EFI_UGA_PIXEL)); + Args->Delta -= Args->Width * sizeof (EFI_UGA_PIXEL); + for (SrcY = Args->SourceY; SrcY < (Args->Height + Args->SourceY); SrcY++) { + for (SrcX = Args->SourceX; SrcX < (Args->Width + Args->SourceX); SrcX++) { + *Blt++ = X11ColorToPixel (Private, XGetPixel (Private->image, SrcX, SrcY)); + } + Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Args->Delta); + } + break; + case EfiUgaBltBufferToVideo: + Blt = (EFI_UGA_PIXEL *)((UINT8 *)BltBuffer + (Args->SourceY * Args->Delta) + Args->SourceX * sizeof (EFI_UGA_PIXEL)); + Args->Delta -= Args->Width * sizeof (EFI_UGA_PIXEL); + for (DstY = Args->DestinationY; DstY < (Args->Height + Args->DestinationY); DstY++) { + for (DstX = Args->DestinationX; DstX < (Args->Width + Args->DestinationX); DstX++) { + XPutPixel(Private->image, DstX, DstY, X11PixelToColor(Private, *Blt)); + Blt++; + } + Blt = (EFI_UGA_PIXEL *) ((UINT8 *) Blt + Args->Delta); + } + break; + case EfiUgaVideoToVideo: + Dst = Private->image_data + (Args->DestinationX << Private->pixel_shift) + + Args->DestinationY * Private->line_bytes; + Src = Private->image_data + (Args->SourceX << Private->pixel_shift) + + Args->SourceY * Private->line_bytes; + Nbr = Args->Width << Private->pixel_shift; + if (Args->DestinationY < Args->SourceY) { + for (Index = 0; Index < Args->Height; Index++) { + memcpy (Dst, Src, Nbr); + Dst += Private->line_bytes; + Src += Private->line_bytes; + } + } else { + Dst += (Args->Height - 1) * Private->line_bytes; + Src += (Args->Height - 1) * Private->line_bytes; + for (Index = 0; Index < Args->Height; Index++) { + // + // Source and Destination Y may be equal, therefore Dst and Src may + // overlap. + // + memmove (Dst, Src, Nbr); + Dst -= Private->line_bytes; + Src -= Private->line_bytes; + } + } + break; + case EfiUgaVideoFill: + Color = X11PixelToColor(Private, *BltBuffer); + for (DstY = Args->DestinationY; DstY < (Args->Height + Args->DestinationY); DstY++) { + for (DstX = Args->DestinationX; DstX < (Args->Width + Args->DestinationX); DstX++) { + XPutPixel(Private->image, DstX, DstY, Color); + } + } + break; + default: + return EFI_INVALID_PARAMETER; + } + + // + // Refresh screen. + // + switch (BltOperation) { + case EfiUgaVideoToVideo: + XCopyArea( + Private->display, Private->win, Private->win, Private->gc, + Args->SourceX, Args->SourceY, Args->Width, Args->Height, + Args->DestinationX, Args->DestinationY + ); + + while (1) { + XNextEvent (Private->display, &ev); + HandleEvent (Private, &ev); + if (ev.type == NoExpose || ev.type == GraphicsExpose) { + break; + } + } + break; + case EfiUgaVideoFill: + Color = X11PixelToColor (Private, *BltBuffer); + XSetForeground (Private->display, Private->gc, Color); + XFillRectangle ( + Private->display, Private->win, Private->gc, + Args->DestinationX, Args->DestinationY, Args->Width, Args->Height + ); + XFlush (Private->display); + break; + case EfiUgaBltBufferToVideo: + Redraw (Private, Args->DestinationX, Args->DestinationY, Args->Width, Args->Height); + break; + default: + break; + } + return EFI_SUCCESS; +} + + +EFI_STATUS +X11CheckPointer ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo + ) +{ + GRAPHICS_IO_PRIVATE *Drv; + + Drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + + HandleEvents (Drv); + if (Drv->pointer_state_changed != 0) { + return EFI_SUCCESS; + } + + return EFI_NOT_READY; +} + + +EFI_STATUS +X11GetPointerState ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_SIMPLE_POINTER_STATE *State + ) +{ + EFI_STATUS EfiStatus; + GRAPHICS_IO_PRIVATE *Drv; + + Drv = (GRAPHICS_IO_PRIVATE *)GraphicsIo; + + EfiStatus = X11CheckPointer (GraphicsIo); + if (EfiStatus != EFI_SUCCESS) { + return EfiStatus; + } + + memcpy (State, &Drv->pointer_state, sizeof (EFI_SIMPLE_POINTER_STATE)); + + Drv->pointer_state.RelativeMovementX = 0; + Drv->pointer_state.RelativeMovementY = 0; + Drv->pointer_state.RelativeMovementZ = 0; + Drv->pointer_state_changed = 0; + return EFI_SUCCESS; +} + + + +EFI_STATUS +X11GraphicsWindowOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + GRAPHICS_IO_PRIVATE *Drv; + unsigned int border_width = 0; + char *display_name = NULL; + + Drv = (GRAPHICS_IO_PRIVATE *)calloc (1, sizeof (GRAPHICS_IO_PRIVATE)); + if (Drv == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Drv->GraphicsIo.Size = GasketX11Size; + Drv->GraphicsIo.CheckKey = GasketX11CheckKey; + Drv->GraphicsIo.GetKey = GasketX11GetKey; + Drv->GraphicsIo.KeySetState = GasketX11KeySetState; + Drv->GraphicsIo.RegisterKeyNotify = GasketX11RegisterKeyNotify; + Drv->GraphicsIo.Blt = GasketX11Blt; + Drv->GraphicsIo.CheckPointer = GasketX11CheckPointer; + Drv->GraphicsIo.GetPointerState = GasketX11GetPointerState; + + + Drv->key_count = 0; + Drv->key_rd = 0; + Drv->key_wr = 0; + Drv->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID; + Drv->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID; + Drv->MakeRegisterdKeyCallback = NULL; + Drv->BreakRegisterdKeyCallback = NULL; + Drv->RegisterdKeyCallbackContext = NULL; + + + Drv->display = XOpenDisplay (display_name); + if (Drv->display == NULL) { + fprintf (stderr, "uga: cannot connect to X server %s\n", XDisplayName (display_name)); + free (Drv); + return EFI_DEVICE_ERROR; + } + Drv->screen = DefaultScreen (Drv->display); + Drv->visual = DefaultVisual (Drv->display, Drv->screen); + Drv->win = XCreateSimpleWindow ( + Drv->display, RootWindow (Drv->display, Drv->screen), + 0, 0, 4, 4, border_width, + WhitePixel (Drv->display, Drv->screen), + BlackPixel (Drv->display, Drv->screen) + ); + + Drv->depth = DefaultDepth (Drv->display, Drv->screen); + XDefineCursor (Drv->display, Drv->win, XCreateFontCursor (Drv->display, XC_pirate)); + + Drv->Title = malloc (StrSize (This->ConfigString)); + UnicodeStrToAsciiStrS (This->ConfigString, Drv->Title, StrSize (This->ConfigString)); + XStoreName (Drv->display, Drv->win, Drv->Title); + +// XAutoRepeatOff (Drv->display); + XSelectInput ( + Drv->display, Drv->win, + ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask + ); + Drv->gc = DefaultGC (Drv->display, Drv->screen); + + This->Private = (VOID *)Drv; + This->Interface = (VOID *)Drv; + return EFI_SUCCESS; +} + + +EFI_STATUS +X11GraphicsWindowClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + GRAPHICS_IO_PRIVATE *Drv; + + Drv = (GRAPHICS_IO_PRIVATE *)This->Private; + + if (Drv == NULL) { + return EFI_SUCCESS; + } + + if (Drv->image != NULL) { + XDestroyImage(Drv->image); + + if (Drv->use_shm) { + shmdt (Drv->image_data); + } + + Drv->image_data = NULL; + Drv->image = NULL; + } + XDestroyWindow (Drv->display, Drv->win); + XCloseDisplay (Drv->display); + +#ifdef __APPLE__ + // Free up the shared memory + shmctl (Drv->xshm_info.shmid, IPC_RMID, NULL); +#endif + + free (Drv); + return EFI_SUCCESS; +} + + +EMU_IO_THUNK_PROTOCOL gX11ThunkIo = { + &gEmuGraphicsWindowProtocolGuid, + NULL, + NULL, + 0, + GasketX11GraphicsWindowOpen, + GasketX11GraphicsWindowClose, + NULL +}; + + diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/X11IncludeHack b/CdeEmuPkg/EmulatorPkg/Unix/Host/X11IncludeHack new file mode 100644 index 00000000000..f7ab103f697 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/X11IncludeHack @@ -0,0 +1 @@ +/opt/X11/include \ No newline at end of file diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/X64/Gasket.S b/CdeEmuPkg/EmulatorPkg/Unix/Host/X64/Gasket.S new file mode 100644 index 00000000000..5015f226a3b --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/X64/Gasket.S @@ -0,0 +1,1625 @@ +#------------------------------------------------------------------------------ +# +# Manage differenced between UNIX ABI and EFI/Windows ABI +# +# EFI Arg passing: RCX, RDX, R8, R9 +# Callee allocates 32 bytes on stack to spill registers +# UNIX Arg passing: RDI, RSI, RDX, RCX, R8, R9 +# RSI, RDI calle-save on EFI, scatch on UNIX callign +# +# Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#------------------------------------------------------------------------------ + +// +// Gaskets are EFI ABI to UNIX ABI calls +// EFI ABI code will sub 40 (0x28) from %rsp before calling a function +// This is the 32 (0x20) byte to spill registers and 8 bytes to align stack on 16 byte boundary. +// + .text + +// 32 byte shadow to spill rcx-r9, 8 bytes to align stack on 16 byte boundary +// Any call with 0 - 4 arguments allocates 40 bytes on the stack. +// For more than 4 args you always have to increase in quanta of 16 so 5 or 6 args is 56, +// 7 or 8 args is 72, and 9 or 10 args is 88 + + + + .text + +// +// EMU_THUNK_PROTOCOL gaskets (EFIAPI to UNIX ABI) +// + + + + +ASM_GLOBAL ASM_PFX(GasketSecWriteStdErr) +ASM_PFX(GasketSecWriteStdErr): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(SecWriteStdErr) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecConfigStdIn) +ASM_PFX(GasketSecConfigStdIn): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + call ASM_PFX(SecConfigStdIn) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketSecWriteStdOut) +ASM_PFX(GasketSecWriteStdOut): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(SecWriteStdOut) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketSecReadStdIn) +ASM_PFX(GasketSecReadStdIn): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(SecReadStdIn) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketSecPollStdIn) +ASM_PFX(GasketSecPollStdIn): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + call ASM_PFX(SecPollStdIn) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketSecMalloc) +ASM_PFX(GasketSecMalloc): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(SecMalloc) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketSecValloc) +ASM_PFX(GasketSecValloc): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(SecValloc) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketSecFree) +ASM_PFX(GasketSecFree): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(SecFree) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecSetTimer) +ASM_PFX(GasketSecSetTimer): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(SecSetTimer) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecEnableInterrupt) +ASM_PFX(GasketSecEnableInterrupt): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + call ASM_PFX(SecEnableInterrupt) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecDisableInterrupt) +ASM_PFX(GasketSecDisableInterrupt): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + call ASM_PFX(SecDisableInterrupt) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketQueryPerformanceFrequency) +ASM_PFX(GasketQueryPerformanceFrequency): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + call ASM_PFX(QueryPerformanceFrequency) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketQueryPerformanceCounter) +ASM_PFX(GasketQueryPerformanceCounter): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + call ASM_PFX(QueryPerformanceCounter) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecSleep) +ASM_PFX(GasketSecSleep): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(SecSleep) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecCpuSleep) +ASM_PFX(GasketSecCpuSleep): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + call ASM_PFX(SecCpuSleep) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecExit) +ASM_PFX(GasketSecExit): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + movq %rcx, %rdi // Swizzle args + call ASM_PFX(SecExit) // Less to do as we will never return to EFI ABI world +LDEAD_LOOP: + jmp LDEAD_LOOP // _exit should never return + + +ASM_GLOBAL ASM_PFX(GasketSecGetTime) +ASM_PFX(GasketSecGetTime): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(SecGetTime) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketSecSetTime) +ASM_PFX(GasketSecSetTime): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(SecSetTime) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecGetNextProtocol) +ASM_PFX(GasketSecGetNextProtocol): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(SecGetNextProtocol) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +// PPIs produced by SEC + +ASM_GLOBAL ASM_PFX(GasketSecPeCoffGetEntryPoint) +ASM_PFX(GasketSecPeCoffGetEntryPoint): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(SecPeCoffGetEntryPoint) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketSecPeCoffRelocateImageExtraAction) +ASM_PFX(GasketSecPeCoffRelocateImageExtraAction): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(SecPeCoffRelocateImageExtraAction) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketSecPeCoffUnloadImageExtraAction) +ASM_PFX(GasketSecPeCoffUnloadImageExtraAction): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(SecPeCoffUnloadImageExtraAction) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecEmuThunkAddress) +ASM_PFX(GasketSecEmuThunkAddress): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + call ASM_PFX(SecEmuThunkAddress) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +// +// Gasket functions for EFI_EMU_UGA_IO_PROTOCOL +// + +ASM_GLOBAL ASM_PFX(GasketX11Size) +ASM_PFX(GasketX11Size): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(X11Size) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11CheckKey) +ASM_PFX(GasketX11CheckKey): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(X11CheckKey) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketX11GetKey) +ASM_PFX(GasketX11GetKey): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(X11GetKey) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11KeySetState) +ASM_PFX(GasketX11KeySetState): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(X11KeySetState) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11RegisterKeyNotify) +ASM_PFX(GasketX11RegisterKeyNotify): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(X11RegisterKeyNotify) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11Blt) +ASM_PFX(GasketX11Blt): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(X11Blt) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11CheckPointer) +ASM_PFX(GasketX11CheckPointer): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(X11CheckPointer) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11GetPointerState) +ASM_PFX(GasketX11GetPointerState): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(X11GetPointerState) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11GraphicsWindowOpen) +ASM_PFX(GasketX11GraphicsWindowOpen): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(X11GraphicsWindowOpen) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketX11GraphicsWindowClose) +ASM_PFX(GasketX11GraphicsWindowClose): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %r9, %rcx + + call ASM_PFX(X11GraphicsWindowClose) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +// Pthreads + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexLock) +ASM_PFX(GasketPthreadMutexLock): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadMutexLock) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexUnLock) +ASM_PFX(GasketPthreadMutexUnLock): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadMutexUnLock) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexTryLock) +ASM_PFX(GasketPthreadMutexTryLock): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadMutexTryLock) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexInit) +ASM_PFX(GasketPthreadMutexInit): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + + call ASM_PFX(PthreadMutexInit) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + + +ASM_GLOBAL ASM_PFX(GasketPthreadMutexDestroy) +ASM_PFX(GasketPthreadMutexDestroy): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadMutexDestroy) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadCreate) +ASM_PFX(GasketPthreadCreate): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(PthreadCreate) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadExit) +ASM_PFX(GasketPthreadExit): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadExit) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + + +ASM_GLOBAL ASM_PFX(GasketPthreadSelf) +ASM_PFX(GasketPthreadSelf): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + + call ASM_PFX(PthreadSelf) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadOpen) +ASM_PFX(GasketPthreadOpen): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadOpen) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPthreadClose) +ASM_PFX(GasketPthreadClose): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PthreadClose) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + + + +// +// UNIX ABI to EFI ABI call +// +// UINTN +// ReverseGasketUint64 ( +// void *Api, +// UINTN Arg1 +// ); +ASM_GLOBAL ASM_PFX(ReverseGasketUint64) +ASM_PFX(ReverseGasketUint64): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + movq %rdi, %rax // Swizzle args + movq %rsi, %rcx + + subq $32, %rsp // 32-byte shadow space + call *%rax + addq $32, %rsp + + popq %rbp + ret + +// +// UNIX ABI to EFI ABI call +// +// UINTN +// ReverseGasketUint64Uint64 ( +// void *Api, +// UINTN Arg1 +// UINTN Arg2 +// ); +ASM_GLOBAL ASM_PFX(ReverseGasketUint64Uint64) +ASM_PFX(ReverseGasketUint64Uint64): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + movq %rdi, %rax // Swizzle args + movq %rsi, %rcx + + subq $32, %rsp // 32-byte shadow space + call *%rax + addq $32, %rsp + + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecUnixPeiAutoScan) +ASM_PFX(GasketSecUnixPeiAutoScan): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + + call ASM_PFX(SecUnixPeiAutoScan) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSecUnixFdAddress) +ASM_PFX(GasketSecUnixFdAddress): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(SecUnixFdAddress) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +// EmuIoThunk SimpleFileSystem + +ASM_GLOBAL ASM_PFX(GasketPosixOpenVolume) +ASM_PFX(GasketPosixOpenVolume): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(PosixOpenVolume) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileOpen) +ASM_PFX(GasketPosixFileOpen): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + movq 48(%rbp), %r8 + + call ASM_PFX(PosixFileOpen) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileCLose) +ASM_PFX(GasketPosixFileCLose): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PosixFileCLose) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileDelete) +ASM_PFX(GasketPosixFileDelete): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PosixFileDelete) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileRead) +ASM_PFX(GasketPosixFileRead): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + + call ASM_PFX(PosixFileRead) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileWrite) +ASM_PFX(GasketPosixFileWrite): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + + call ASM_PFX(PosixFileWrite) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileSetPossition) +ASM_PFX(GasketPosixFileSetPossition): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(PosixFileSetPossition) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileGetPossition) +ASM_PFX(GasketPosixFileGetPossition): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(PosixFileGetPossition) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileGetInfo) +ASM_PFX(GasketPosixFileGetInfo): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(PosixFileGetInfo) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileSetInfo) +ASM_PFX(GasketPosixFileSetInfo): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(PosixFileSetInfo) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileFlush) +ASM_PFX(GasketPosixFileFlush): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PosixFileFlush) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileSystmeThunkOpen) +ASM_PFX(GasketPosixFileSystmeThunkOpen): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PosixFileSystmeThunkOpen) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketPosixFileSystmeThunkClose) +ASM_PFX(GasketPosixFileSystmeThunkClose): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(PosixFileSystmeThunkClose) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoReset) +ASM_PFX(GasketEmuBlockIoReset): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(EmuBlockIoReset) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoReadBlocks) +ASM_PFX(GasketEmuBlockIoReadBlocks): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + movq 48(%rbp), %r8 + movq 56(%rbp), %r9 + + call ASM_PFX(EmuBlockIoReadBlocks) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoWriteBlocks) +ASM_PFX(GasketEmuBlockIoWriteBlocks): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + movq 48(%rbp), %r8 + movq 56(%rbp), %r9 + + call ASM_PFX(EmuBlockIoWriteBlocks) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoFlushBlocks) +ASM_PFX(GasketEmuBlockIoFlushBlocks): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(EmuBlockIoFlushBlocks) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketEmuBlockIoCreateMapping) +ASM_PFX(GasketEmuBlockIoCreateMapping): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(EmuBlockIoCreateMapping) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketBlockIoThunkOpen) +ASM_PFX(GasketBlockIoThunkOpen): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(EmuBlockIoThunkOpen) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketBlockIoThunkClose) +ASM_PFX(GasketBlockIoThunkClose): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(EmuBlockIoThunkClose) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + + +ASM_GLOBAL ASM_PFX(GasketSnpCreateMapping) +ASM_PFX(GasketSnpCreateMapping): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(EmuSnpCreateMapping) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpStart) +ASM_PFX(GasketSnpStart): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(EmuSnpStart) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpStop) +ASM_PFX(GasketSnpStop): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(EmuSnpStop) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpInitialize) +ASM_PFX(GasketSnpInitialize): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + + call ASM_PFX(EmuSnpInitialize) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + + +ASM_GLOBAL ASM_PFX(GasketSnpReset) +ASM_PFX(GasketSnpReset): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + + call ASM_PFX(EmuSnpReset) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpShutdown) +ASM_PFX(GasketSnpShutdown): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(EmuSnpShutdown) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpReceiveFilters) +ASM_PFX(GasketSnpReceiveFilters): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + movq 48(%rbp), %r8 + movq 56(%rbp), %r9 + + call ASM_PFX(EmuSnpReceiveFilters) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpStationAddress) +ASM_PFX(GasketSnpStationAddress): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + + call ASM_PFX(EmuSnpStationAddress) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + + +ASM_GLOBAL ASM_PFX(GasketSnpStatistics) +ASM_PFX(GasketSnpStatistics): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(EmuSnpStatistics) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpMCastIpToMac) +ASM_PFX(GasketSnpMCastIpToMac): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + + call ASM_PFX(EmuSnpMCastIpToMac) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpNvData) +ASM_PFX(GasketSnpNvData): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + movq 48(%rbp), %r8 + + call ASM_PFX(EmuSnpNvData) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpGetStatus) +ASM_PFX(GasketSnpGetStatus): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + + call ASM_PFX(EmuSnpGetStatus) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + + +ASM_GLOBAL ASM_PFX(GasketSnpTransmit) +ASM_PFX(GasketSnpTransmit): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + subq $16, %rsp // Allocate space for args on the stack + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + movq 48(%rbp), %r8 + movq 56(%rbp), %r9 + movq 64(%rbp), %rax + movq %rax, (%rsp) + + call ASM_PFX(EmuSnpTransmit) + addq $16, %rsp + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + + +ASM_GLOBAL ASM_PFX(GasketSnpReceive) +ASM_PFX(GasketSnpReceive): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + subq $16, %rsp // Allocate space for args on the stack + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + movq %rdx, %rsi + movq %r8, %rdx + movq %r9, %rcx + movq 48(%rbp), %r8 + movq 56(%rbp), %r9 + movq 64(%rbp), %rax + movq %rax, (%rsp) + + call ASM_PFX(EmuSnpReceive) + addq $16, %rsp + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpThunkOpen) +ASM_PFX(GasketSnpThunkOpen): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(EmuSnpThunkOpen) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + +ASM_GLOBAL ASM_PFX(GasketSnpThunkClose) +ASM_PFX(GasketSnpThunkClose): + pushq %rbp // stack frame is for the debugger + movq %rsp, %rbp + + pushq %rsi // %rsi & %rdi are volatile in Unix and callee-save in EFI ABI + pushq %rdi + + movq %rcx, %rdi // Swizzle args + + call ASM_PFX(EmuSnpThunkClose) + + popq %rdi // restore state + popq %rsi + popq %rbp + ret + + diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Host/X64/SwitchStack.S b/CdeEmuPkg/EmulatorPkg/Unix/Host/X64/SwitchStack.S new file mode 100644 index 00000000000..0dd099259dd --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Host/X64/SwitchStack.S @@ -0,0 +1,47 @@ +#------------------------------------------------------------------------------ +# +# 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 +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# Routine Description: +# +# Routine for switching stacks with 2 parameters EFI ABI +# Convert UNIX to EFI ABI +# +# Arguments: +# +# (rdi) EntryPoint - Entry point with new stack. +# (rsi) Context1 - Parameter1 for entry point. (rcx) +# (rdx) Context2 - Parameter2 for entry point. (rdx) +# (rcx) NewStack - The pointer to new stack. +# +# Returns: +# +# None +# +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(PeiSwitchStacks) +ASM_PFX(PeiSwitchStacks): + pushq $0 // tells gdb to stop unwinding frame + movq %rsp, %rbp + + movq %rcx, %rsp // update stack pointer + + movq %rdi, %rax // entry point to %rax + movq %rsi, %rcx // Adjust Context1 + // Context2 already in the rigth spot + + # + # Reserve space for register parameters (rcx, rdx, r8 & r9) on the stack, + # in case the callee wishes to spill them. + # + subq $32, %rsp // 32-byte shadow space plus alignment pad + call *%rax + + + diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project32/XcodeBuild.sh b/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project32/XcodeBuild.sh new file mode 100644 index 00000000000..5479880b88a --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project32/XcodeBuild.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# +# External makefile Xcode project project uses this script to build and clean from the Xcode GUI +# +# Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +# force exit on error +set -e + +# +# Source the workspace and set up the environment variables we need +# +cd ../../.. +./build.sh -a IA32 $1 $2 $3 $4 $5 $6 $8 diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project32/xcode_project.xcodeproj/default.pbxuser b/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project32/xcode_project.xcodeproj/default.pbxuser new file mode 100644 index 00000000000..7c13f047d21 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project32/xcode_project.xcodeproj/default.pbxuser @@ -0,0 +1,191 @@ +// !$*UTF8*$! +{ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + activeBuildConfigurationName = Debug; + activeExecutable = BA11A1010FB10BCE00D06FEC /* Host.dll */; + activeTarget = D28A88AD04BDD90700651E21 /* xcode_project */; + breakpoints = ( + BA11A11A0FB10E0700D06FEC /* SecGdbConfigBreak */, + ); + codeSenseManager = BA11A0FE0FB10B4800D06FEC /* Code sense */; + executables = ( + BA11A1010FB10BCE00D06FEC /* Host.dll */, + ); + perUserDictionary = { + "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 20, + 198, + 20, + 99, + 99, + 29, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXBreakpointsDataSource_ActionID, + PBXBreakpointsDataSource_TypeID, + PBXBreakpointsDataSource_BreakpointID, + PBXBreakpointsDataSource_UseID, + PBXBreakpointsDataSource_LocationID, + PBXBreakpointsDataSource_ConditionID, + PBXBreakpointsDataSource_IgnoreCountID, + PBXBreakpointsDataSource_ContinueID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 22, + 300, + 229, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXExecutablesDataSource_ActiveFlagID, + PBXExecutablesDataSource_NameID, + PBXExecutablesDataSource_CommentsID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 341, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 263260969; + PBXWorkspaceStateSaveDate = 263260969; + }; + sourceControlManager = BA11A0FD0FB10B4800D06FEC /* Source Control */; + userBuildSettings = { + }; + }; + BA11A0FD0FB10B4800D06FEC /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + repositoryNamesForRoots = { + }; + scmConfiguration = { + }; + }; + BA11A0FE0FB10B4800D06FEC /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + BA11A1010FB10BCE00D06FEC /* Host.dll */ = { + isa = PBXExecutable; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + breakpointsEnabled = 1; + configStateDict = { + "PBXLSLaunchAction-0" = { + PBXLSLaunchAction = 0; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXLSRunLaunchConfig; + commandLineArgs = ( + ); + displayName = "Executable Runner"; + environment = { + }; + identifier = com.apple.Xcode.launch.runConfig; + remoteHostInfo = ""; + startActionInfo = ""; + }; + "PBXLSLaunchAction-1" = { + PBXLSLaunchAction = 1; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXGDB_LaunchConfig; + commandLineArgs = ( + ); + displayName = GDB; + environment = { + }; + identifier = com.apple.Xcode.launch.GDBMI_Config; + remoteHostInfo = ""; + startActionInfo = ""; + }; + }; + customDataFormattersEnabled = 0; + dataTipCustomDataFormattersEnabled = 1; + dataTipShowTypeColumn = 1; + dataTipSortType = 0; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + launchableReference = BA11A1020FB10BCE00D06FEC /* Host.dll */; + libgmallocEnabled = 0; + name = Host.dll; + savedGlobals = { + }; + showTypeColumn = 0; + sourceDirectories = ( + ); + startupPath = ../../../../Build/Emulator32/DEBUG_XCLANG/IA32; + }; + BA11A1020FB10BCE00D06FEC /* Host.dll */ = { + isa = PBXFileReference; + lastKnownFileType = "compiled.mach-o.executable"; + name = Host.dll; + path = ../../../../Build/Emulator32/DEBUG_XCLANG/IA32/Host; + sourceTree = SOURCE_ROOT; + }; + BA11A11A0FB10E0700D06FEC /* SecGdbConfigBreak */ = { + isa = PBXSymbolicBreakpoint; + actions = ( + BA11A11E0FB10E2200D06FEC /* XCBreakpointCommandAction */, + ); + breakpointStyle = 1; + continueAfterActions = 1; + countType = 0; + delayBeforeContinue = 0; + hitCount = 0; + ignoreCount = 0; + location = Host; + modificationTime = 263261853.260195; + originalNumberOfMultipleMatches = 1; + state = 1; + symbolName = SecGdbConfigBreak; + }; + BA11A11E0FB10E2200D06FEC /* XCBreakpointCommandAction */ = { + isa = XCBreakpointCommandAction; + command = "set gInXcode=1\nsource ../../../../EmulatorPkg/Unix/GdbRun.sh"; + fallbackIsa = XCBreakpointAction; + logCommand = 0; + useDebuggerSideImplementation = 1; + }; + D28A88AD04BDD90700651E21 /* xcode_project */ = { + activeExec = 0; + }; +} diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project32/xcode_project.xcodeproj/project.pbxproj b/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project32/xcode_project.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..8ff531ef6c0 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project32/xcode_project.xcodeproj/project.pbxproj @@ -0,0 +1,124 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* xcode_project */ = { + isa = PBXGroup; + children = ( + ); + name = xcode_project; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXLegacyTarget section */ + D28A88AD04BDD90700651E21 /* xcode_project */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION)"; + buildConfigurationList = 1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "xcode_project" */; + buildPhases = ( + ); + buildToolPath = ./XcodeBuild.sh; + buildWorkingDirectory = ""; + dependencies = ( + ); + name = xcode_project; + passBuildSettingsInEnvironment = 1; + productName = xcode_project; + }; +/* End PBXLegacyTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "xcode_project" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 08FB7794FE84155DC02AAC07 /* xcode_project */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D28A88AD04BDD90700651E21 /* xcode_project */, + ); + }; +/* End PBXProject section */ + +/* Begin XCBuildConfiguration section */ + 1DEB919008733D9F0010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = xcode_project; + }; + name = Debug; + }; + 1DEB919108733D9F0010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = xcode_project; + }; + name = Release; + }; + 1DEB919408733D9F0010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = macosx10.6; + }; + name = Debug; + }; + 1DEB919508733D9F0010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = macosx10.6; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "xcode_project" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB919008733D9F0010E9CD /* Debug */, + 1DEB919108733D9F0010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "xcode_project" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB919408733D9F0010E9CD /* Debug */, + 1DEB919508733D9F0010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project64/XcodeBuild.sh b/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project64/XcodeBuild.sh new file mode 100644 index 00000000000..9f90ef1c3bf --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project64/XcodeBuild.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# +# External makefile Xcode project project uses this script to build and clean from the Xcode GUI +# +# Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +# force exit on error +set -e + +# +# Source the workspace and set up the environment variables we need +# +cd ../../.. +./build.sh $1 $2 $3 $4 $5 $6 $8 diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/default.pbxuser b/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/default.pbxuser new file mode 100644 index 00000000000..d8bd924660d --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/default.pbxuser @@ -0,0 +1,191 @@ +// !$*UTF8*$! +{ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + activeBuildConfigurationName = Debug; + activeExecutable = BA11A1010FB10BCE00D06FEC /* Host.dll */; + activeTarget = D28A88AD04BDD90700651E21 /* xcode_project */; + breakpoints = ( + BA11A11A0FB10E0700D06FEC /* SecGdbConfigBreak */, + ); + codeSenseManager = BA11A0FE0FB10B4800D06FEC /* Code sense */; + executables = ( + BA11A1010FB10BCE00D06FEC /* Host.dll */, + ); + perUserDictionary = { + "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 20, + 198, + 20, + 99, + 99, + 29, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXBreakpointsDataSource_ActionID, + PBXBreakpointsDataSource_TypeID, + PBXBreakpointsDataSource_BreakpointID, + PBXBreakpointsDataSource_UseID, + PBXBreakpointsDataSource_LocationID, + PBXBreakpointsDataSource_ConditionID, + PBXBreakpointsDataSource_IgnoreCountID, + PBXBreakpointsDataSource_ContinueID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 22, + 300, + 229, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXExecutablesDataSource_ActiveFlagID, + PBXExecutablesDataSource_NameID, + PBXExecutablesDataSource_CommentsID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 341, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 263260969; + PBXWorkspaceStateSaveDate = 263260969; + }; + sourceControlManager = BA11A0FD0FB10B4800D06FEC /* Source Control */; + userBuildSettings = { + }; + }; + BA11A0FD0FB10B4800D06FEC /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + repositoryNamesForRoots = { + }; + scmConfiguration = { + }; + }; + BA11A0FE0FB10B4800D06FEC /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + BA11A1010FB10BCE00D06FEC /* Host.dll */ = { + isa = PBXExecutable; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + breakpointsEnabled = 1; + configStateDict = { + "PBXLSLaunchAction-0" = { + PBXLSLaunchAction = 0; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXLSRunLaunchConfig; + commandLineArgs = ( + ); + displayName = "Executable Runner"; + environment = { + }; + identifier = com.apple.Xcode.launch.runConfig; + remoteHostInfo = ""; + startActionInfo = ""; + }; + "PBXLSLaunchAction-1" = { + PBXLSLaunchAction = 1; + PBXLSLaunchStartAction = 1; + PBXLSLaunchStdioStyle = 2; + PBXLSLaunchStyle = 0; + class = PBXGDB_LaunchConfig; + commandLineArgs = ( + ); + displayName = GDB; + environment = { + }; + identifier = com.apple.Xcode.launch.GDBMI_Config; + remoteHostInfo = ""; + startActionInfo = ""; + }; + }; + customDataFormattersEnabled = 0; + dataTipCustomDataFormattersEnabled = 1; + dataTipShowTypeColumn = 1; + dataTipSortType = 0; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + launchableReference = BA11A1020FB10BCE00D06FEC /* Host.dll */; + libgmallocEnabled = 0; + name = Host.dll; + savedGlobals = { + }; + showTypeColumn = 0; + sourceDirectories = ( + ); + startupPath = ../../../../Build/Emulator/DEBUG_XCLANG/X64; + }; + BA11A1020FB10BCE00D06FEC /* Host.dll */ = { + isa = PBXFileReference; + lastKnownFileType = "compiled.mach-o.executable"; + name = Host.dll; + path = ../../../../Build/Emulator/DEBUG_XCLANG/X64/Host; + sourceTree = SOURCE_ROOT; + }; + BA11A11A0FB10E0700D06FEC /* SecGdbConfigBreak */ = { + isa = PBXSymbolicBreakpoint; + actions = ( + BA11A11E0FB10E2200D06FEC /* XCBreakpointCommandAction */, + ); + breakpointStyle = 1; + continueAfterActions = 1; + countType = 0; + delayBeforeContinue = 0; + hitCount = 0; + ignoreCount = 0; + location = Host; + modificationTime = 263261853.260195; + originalNumberOfMultipleMatches = 1; + state = 1; + symbolName = SecGdbConfigBreak; + }; + BA11A11E0FB10E2200D06FEC /* XCBreakpointCommandAction */ = { + isa = XCBreakpointCommandAction; + command = "set gInXcode=1\nsource ../../../../EmulatorPkg/Unix/GdbRun.sh"; + fallbackIsa = XCBreakpointAction; + logCommand = 0; + useDebuggerSideImplementation = 1; + }; + D28A88AD04BDD90700651E21 /* xcode_project */ = { + activeExec = 0; + }; +} diff --git a/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/project.pbxproj b/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..9bd13bd63f2 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/Xcode/xcode_project64/xcode_project.xcodeproj/project.pbxproj @@ -0,0 +1,124 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* xcode_project */ = { + isa = PBXGroup; + children = ( + ); + name = xcode_project; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXLegacyTarget section */ + D28A88AD04BDD90700651E21 /* xcode_project */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION)"; + buildConfigurationList = 1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "xcode_project" */; + buildPhases = ( + ); + buildToolPath = ./XcodeBuild.sh; + buildWorkingDirectory = ""; + dependencies = ( + ); + name = xcode_project; + passBuildSettingsInEnvironment = 1; + productName = xcode_project; + }; +/* End PBXLegacyTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "xcode_project" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 08FB7794FE84155DC02AAC07 /* xcode_project */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + D28A88AD04BDD90700651E21 /* xcode_project */, + ); + }; +/* End PBXProject section */ + +/* Begin XCBuildConfiguration section */ + 1DEB919008733D9F0010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = xcode_project; + }; + name = Debug; + }; + 1DEB919108733D9F0010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = xcode_project; + }; + name = Release; + }; + 1DEB919408733D9F0010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = macosx10.6; + }; + name = Debug; + }; + 1DEB919508733D9F0010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = macosx10.6; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "xcode_project" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB919008733D9F0010E9CD /* Debug */, + 1DEB919108733D9F0010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "xcode_project" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB919408733D9F0010E9CD /* Debug */, + 1DEB919508733D9F0010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} diff --git a/CdeEmuPkg/EmulatorPkg/Unix/lldbefi.py b/CdeEmuPkg/EmulatorPkg/Unix/lldbefi.py new file mode 100644 index 00000000000..5cdc14ce444 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/lldbefi.py @@ -0,0 +1,541 @@ +#!/usr/bin/python + +# +# Copyright 2014 Apple Inc. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +import lldb +import os +import uuid +import string +import commands +import optparse +import shlex + +guid_dict = {} + + +def EFI_GUID_TypeSummary (valobj,internal_dict): + """ Type summary for EFI GUID, print C Name if known + """ + # typedef struct { + # UINT32 Data1; + # UINT16 Data2; + # UINT16 Data3; + # UINT8 Data4[8]; + # } EFI_GUID; + SBError = lldb.SBError() + + data1_val = valobj.GetChildMemberWithName('Data1') + data1 = data1_val.GetValueAsUnsigned(0) + data2_val = valobj.GetChildMemberWithName('Data2') + data2 = data2_val.GetValueAsUnsigned(0) + data3_val = valobj.GetChildMemberWithName('Data3') + data3 = data3_val.GetValueAsUnsigned(0) + str = "%x-%x-%x-" % (data1, data2, data3) + + data4_val = valobj.GetChildMemberWithName('Data4') + for i in range (data4_val.num_children): + if i == 2: + str +='-' + str += "%02x" % data4_val.GetChildAtIndex(i).data.GetUnsignedInt8(SBError, 0) + + return guid_dict.get (str.upper(), '') + + + +EFI_STATUS_Dict = { + (0x8000000000000000 | 1): "Load Error", + (0x8000000000000000 | 2): "Invalid Parameter", + (0x8000000000000000 | 3): "Unsupported", + (0x8000000000000000 | 4): "Bad Buffer Size", + (0x8000000000000000 | 5): "Buffer Too Small", + (0x8000000000000000 | 6): "Not Ready", + (0x8000000000000000 | 7): "Device Error", + (0x8000000000000000 | 8): "Write Protected", + (0x8000000000000000 | 9): "Out of Resources", + (0x8000000000000000 | 10): "Volume Corrupt", + (0x8000000000000000 | 11): "Volume Full", + (0x8000000000000000 | 12): "No Media", + (0x8000000000000000 | 13): "Media changed", + (0x8000000000000000 | 14): "Not Found", + (0x8000000000000000 | 15): "Access Denied", + (0x8000000000000000 | 16): "No Response", + (0x8000000000000000 | 17): "No mapping", + (0x8000000000000000 | 18): "Time out", + (0x8000000000000000 | 19): "Not started", + (0x8000000000000000 | 20): "Already started", + (0x8000000000000000 | 21): "Aborted", + (0x8000000000000000 | 22): "ICMP Error", + (0x8000000000000000 | 23): "TFTP Error", + (0x8000000000000000 | 24): "Protocol Error", + + 0 : "Success", + 1 : "Warning Unknown Glyph", + 2 : "Warning Delete Failure", + 3 : "Warning Write Failure", + 4 : "Warning Buffer Too Small", + + (0x80000000 | 1): "Load Error", + (0x80000000 | 2): "Invalid Parameter", + (0x80000000 | 3): "Unsupported", + (0x80000000 | 4): "Bad Buffer Size", + (0x80000000 | 5): "Buffer Too Small", + (0x80000000 | 6): "Not Ready", + (0x80000000 | 7): "Device Error", + (0x80000000 | 8): "Write Protected", + (0x80000000 | 9): "Out of Resources", + (0x80000000 | 10): "Volume Corrupt", + (0x80000000 | 11): "Volume Full", + (0x80000000 | 12): "No Media", + (0x80000000 | 13): "Media changed", + (0x80000000 | 14): "Not Found", + (0x80000000 | 15): "Access Denied", + (0x80000000 | 16): "No Response", + (0x80000000 | 17): "No mapping", + (0x80000000 | 18): "Time out", + (0x80000000 | 19): "Not started", + (0x80000000 | 20): "Already started", + (0x80000000 | 21): "Aborted", + (0x80000000 | 22): "ICMP Error", + (0x80000000 | 23): "TFTP Error", + (0x80000000 | 24): "Protocol Error", +} + +def EFI_STATUS_TypeSummary (valobj,internal_dict): + # + # Return summary string for EFI_STATUS from dictionary + # + Status = valobj.GetValueAsUnsigned(0) + return EFI_STATUS_Dict.get (Status, '') + + +def EFI_TPL_TypeSummary (valobj,internal_dict): + # + # Return TPL values + # + + if valobj.TypeIsPointerType(): + return "" + + Tpl = valobj.GetValueAsUnsigned(0) + if Tpl < 4: + Str = "%d" % Tpl + elif Tpl == 6: + Str = "TPL_DRIVER (Obsolete Concept in edk2)" + elif Tpl < 8: + Str = "TPL_APPLICATION" + if Tpl - 4 > 0: + Str += " + " + "%d" % (Tpl - 4) + elif Tpl < 16: + Str = "TPL_CALLBACK" + if Tpl - 8 > 0: + Str += " + " + "%d" % (Tpl - 4) + elif Tpl < 31: + Str = "TPL_NOTIFY" + if Tpl - 16 > 0: + Str += " + " + "%d" % (Tpl - 4) + elif Tpl == 31: + Str = "TPL_HIGH_LEVEL" + else: + Str = "Invalid TPL" + + return Str + + +def CHAR16_TypeSummary (valobj,internal_dict): + # + # Display EFI CHAR16 'unsigned short' as string + # + SBError = lldb.SBError() + Str = '' + if valobj.TypeIsPointerType(): + if valobj.GetValueAsUnsigned () == 0: + return "NULL" + + # CHAR16 * max string size 1024 + for i in range (1024): + Char = valobj.GetPointeeData(i,1).GetUnsignedInt16(SBError, 0) + if SBError.fail or Char == 0: + break + Str += unichr (Char) + Str = 'L"' + Str + '"' + return Str.encode ('utf-8', 'replace') + + if valobj.num_children == 0: + # CHAR16 + if chr (valobj.unsigned) in string.printable: + Str = "L'" + unichr (valobj.unsigned) + "'" + return Str.encode ('utf-8', 'replace') + else: + # CHAR16 [] + for i in range (valobj.num_children): + Char = valobj.GetChildAtIndex(i).data.GetUnsignedInt16(SBError, 0) + if Char == 0: + break + Str += unichr (Char) + Str = 'L"' + Str + '"' + return Str.encode ('utf-8', 'replace') + + return Str + +def CHAR8_TypeSummary (valobj,internal_dict): + # + # Display EFI CHAR8 'signed char' as string + # unichr() is used as a junk string can produce an error message like this: + # UnicodeEncodeError: 'ascii' codec can't encode character u'\x90' in position 1: ordinal not in range(128) + # + SBError = lldb.SBError() + Str = '' + if valobj.TypeIsPointerType(): + if valobj.GetValueAsUnsigned () == 0: + return "NULL" + + # CHAR8 * max string size 1024 + for i in range (1024): + Char = valobj.GetPointeeData(i,1).GetUnsignedInt8(SBError, 0) + if SBError.fail or Char == 0: + break + Str += unichr (Char) + Str = '"' + Str + '"' + return Str.encode ('utf-8', 'replace') + + if valobj.num_children == 0: + # CHAR8 + if chr (valobj.unsigned) in string.printable: + Str = '"' + unichr (valobj.unsigned) + '"' + return Str.encode ('utf-8', 'replace') + else: + # CHAR8 [] + for i in range (valobj.num_children): + Char = valobj.GetChildAtIndex(i).data.GetUnsignedInt8(SBError, 0) + if Char == 0: + break + Str += unichr (Char) + Str = '"' + Str + '"' + return Str.encode ('utf-8', 'replace') + + return Str + +device_path_dict = { + (0x01, 0x01): "PCI_DEVICE_PATH", + (0x01, 0x02): "PCCARD_DEVICE_PATH", + (0x01, 0x03): "MEMMAP_DEVICE_PATH", + (0x01, 0x04): "VENDOR_DEVICE_PATH", + (0x01, 0x05): "CONTROLLER_DEVICE_PATH", + (0x02, 0x01): "ACPI_HID_DEVICE_PATH", + (0x02, 0x02): "ACPI_EXTENDED_HID_DEVICE_PATH", + (0x02, 0x03): "ACPI_ADR_DEVICE_PATH", + (0x03, 0x01): "ATAPI_DEVICE_PATH", + (0x03, 0x12): "SATA_DEVICE_PATH", + (0x03, 0x02): "SCSI_DEVICE_PATH", + (0x03, 0x03): "FIBRECHANNEL_DEVICE_PATH", + (0x03, 0x04): "F1394_DEVICE_PATH", + (0x03, 0x05): "USB_DEVICE_PATH", + (0x03, 0x0f): "USB_CLASS_DEVICE_PATH", + (0x03, 0x10): "FW_SBP2_UNIT_LUN_DEVICE_PATH", + (0x03, 0x11): "DEVICE_LOGICAL_UNIT_DEVICE_PATH", + (0x03, 0x06): "I2O_DEVICE_PATH", + (0x03, 0x0b): "MAC_ADDR_DEVICE_PATH", + (0x03, 0x0c): "IPv4_DEVICE_PATH", + (0x03, 0x09): "INFINIBAND_DEVICE_PATH", + (0x03, 0x0e): "UART_DEVICE_PATH", + (0x03, 0x0a): "VENDOR_DEVICE_PATH", + (0x03, 0x13): "ISCSI_DEVICE_PATH", + (0x04, 0x01): "HARDDRIVE_DEVICE_PATH", + (0x04, 0x02): "CDROM_DEVICE_PATH", + (0x04, 0x03): "VENDOR_DEVICE_PATH", + (0x04, 0x04): "FILEPATH_DEVICE_PATH", + (0x04, 0x05): "MEDIA_PROTOCOL_DEVICE_PATH", + (0x05, 0x01): "BBS_BBS_DEVICE_PATH", + (0x7F, 0xFF): "EFI_DEVICE_PATH_PROTOCOL", + (0xFF, 0xFF): "EFI_DEVICE_PATH_PROTOCOL", +} + +def EFI_DEVICE_PATH_PROTOCOL_TypeSummary (valobj,internal_dict): + # + # + # + if valobj.TypeIsPointerType(): + # EFI_DEVICE_PATH_PROTOCOL * + return "" + + Str = "" + if valobj.num_children == 3: + # EFI_DEVICE_PATH_PROTOCOL + Type = valobj.GetChildMemberWithName('Type').unsigned + SubType = valobj.GetChildMemberWithName('SubType').unsigned + if (Type, SubType) in device_path_dict: + TypeStr = device_path_dict[Type, SubType] + else: + TypeStr = "" + + LenLow = valobj.GetChildMemberWithName('Length').GetChildAtIndex(0).unsigned + LenHigh = valobj.GetChildMemberWithName('Length').GetChildAtIndex(1).unsigned + Len = LenLow + (LenHigh >> 8) + + Address = long ("%d" % valobj.addr) + if (Address == lldb.LLDB_INVALID_ADDRESS): + # Need to research this, it seems to be the nested struct case + ExprStr = "" + elif (Type & 0x7f == 0x7f): + ExprStr = "End Device Path" if SubType == 0xff else "End This Instance" + else: + ExprStr = "expr *(%s *)0x%08x" % (TypeStr, Address) + + Str = " {\n" + Str += " (UINT8) Type = 0x%02x // %s\n" % (Type, "END" if (Type & 0x7f == 0x7f) else "") + Str += " (UINT8) SubType = 0x%02x // %s\n" % (SubType, ExprStr) + Str += " (UINT8 [2]) Length = { // 0x%04x (%d) bytes\n" % (Len, Len) + Str += " (UINT8) [0] = 0x%02x\n" % LenLow + Str += " (UINT8) [1] = 0x%02x\n" % LenHigh + Str += " }\n" + if (Type & 0x7f == 0x7f) and (SubType == 0xff): + pass + elif ExprStr != "": + NextNode = Address + Len + Str += "// Next node 'expr *(EFI_DEVICE_PATH_PROTOCOL *)0x%08x'\n" % NextNode + + return Str + + + +def TypePrintFormating(debugger): + # + # Set the default print formatting for EFI types in lldb. + # seems lldb defaults to decimal. + # + category = debugger.GetDefaultCategory() + FormatBool = lldb.SBTypeFormat(lldb.eFormatBoolean) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("BOOLEAN"), FormatBool) + + FormatHex = lldb.SBTypeFormat(lldb.eFormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT64"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT64"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT32"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT32"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT16"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT16"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT8"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT8"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINTN"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("INTN"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("CHAR8"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("CHAR16"), FormatHex) + + category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_PHYSICAL_ADDRESS"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("PHYSICAL_ADDRESS"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_STATUS"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_TPL"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_LBA"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_BOOT_MODE"), FormatHex) + category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_FV_FILETYPE"), FormatHex) + + # + # Smart type printing for EFI + # + debugger.HandleCommand("type summary add EFI_GUID --python-function lldbefi.EFI_GUID_TypeSummary") + debugger.HandleCommand("type summary add EFI_STATUS --python-function lldbefi.EFI_STATUS_TypeSummary") + debugger.HandleCommand("type summary add EFI_TPL --python-function lldbefi.EFI_TPL_TypeSummary") + debugger.HandleCommand("type summary add EFI_DEVICE_PATH_PROTOCOL --python-function lldbefi.EFI_DEVICE_PATH_PROTOCOL_TypeSummary") + + debugger.HandleCommand("type summary add CHAR16 --python-function lldbefi.CHAR16_TypeSummary") + debugger.HandleCommand('type summary add --regex "CHAR16 \[[0-9]+\]" --python-function lldbefi.CHAR16_TypeSummary') + debugger.HandleCommand("type summary add CHAR8 --python-function lldbefi.CHAR8_TypeSummary") + debugger.HandleCommand('type summary add --regex "CHAR8 \[[0-9]+\]" --python-function lldbefi.CHAR8_TypeSummary') + + debugger.HandleCommand( + 'setting set frame-format "frame #${frame.index}: ${frame.pc}' + '{ ${module.file.basename}{:${function.name}()${function.pc-offset}}}' + '{ at ${line.file.fullpath}:${line.number}}\n"' + ) + +gEmulatorBreakWorkaroundNeeded = True + +def LoadEmulatorEfiSymbols(frame, bp_loc , internal_dict): + # + # This is an lldb breakpoint script, and assumes the breakpoint is on a + # function with the same prototype as SecGdbScriptBreak(). The + # argument names are important as lldb looks them up. + # + # VOID + # SecGdbScriptBreak ( + # char *FileName, + # int FileNameLength, + # long unsigned int LoadAddress, + # int AddSymbolFlag + # ) + # { + # return; + # } + # + # When the emulator loads a PE/COFF image, it calls the stub function with + # the filename of the symbol file, the length of the FileName, the + # load address and a flag to indicate if this is a load or unload operation + # + global gEmulatorBreakWorkaroundNeeded + + if gEmulatorBreakWorkaroundNeeded: + # turn off lldb debug prints on SIGALRM (EFI timer tick) + frame.thread.process.target.debugger.HandleCommand("process handle SIGALRM -n false") + gEmulatorBreakWorkaroundNeeded = False + + # Convert C string to Python string + Error = lldb.SBError() + FileNamePtr = frame.FindVariable ("FileName").GetValueAsUnsigned() + FileNameLen = frame.FindVariable ("FileNameLength").GetValueAsUnsigned() + + FileName = frame.thread.process.ReadCStringFromMemory (FileNamePtr, FileNameLen, Error) + if not Error.Success(): + print "!ReadCStringFromMemory() did not find a %d byte C string at %x" % (FileNameLen, FileNamePtr) + # make breakpoint command continue + return False + + debugger = frame.thread.process.target.debugger + if frame.FindVariable ("AddSymbolFlag").GetValueAsUnsigned() == 1: + LoadAddress = frame.FindVariable ("LoadAddress").GetValueAsUnsigned() - 0x240 + + debugger.HandleCommand ("target modules add %s" % FileName) + print "target modules load --slid 0x%x %s" % (LoadAddress, FileName) + debugger.HandleCommand ("target modules load --slide 0x%x --file %s" % (LoadAddress, FileName)) + else: + target = debugger.GetSelectedTarget() + for SBModule in target.module_iter(): + ModuleName = SBModule.GetFileSpec().GetDirectory() + '/' + ModuleName += SBModule.GetFileSpec().GetFilename() + if FileName == ModuleName or FileName == SBModule.GetFileSpec().GetFilename(): + target.ClearModuleLoadAddress (SBModule) + if not target.RemoveModule (SBModule): + print "!lldb.target.RemoveModule (%s) FAILED" % SBModule + + # make breakpoint command continue + return False + +def GuidToCStructStr (guid, Name=False): + # + # Convert a 16-byte bytesarray (or bytearray compat object) to C guid string + # { 0xB402621F, 0xA940, 0x1E4A, { 0x86, 0x6B, 0x4D, 0xC9, 0x16, 0x2B, 0x34, 0x7C } } + # + # Name=True means lookup name in GuidNameDict and us it if you find it + # + + if not isinstance (guid, bytearray): + # convert guid object to UUID, and UUID to bytearray + Uuid = uuid.UUID(guid) + guid = bytearray (Uuid.bytes_le) + + return "{ 0x%02.2X%02.2X%02.2X%02.2X, 0x%02.2X%02.2X, 0x%02.2X%02.2X, { 0x%02.2X, 0x%02.2X, 0x%02.2X, 0x%02.2X, 0x%02.2X, 0x%02.2X, 0x%02.2X, 0x%02.2X } }" % \ + (guid[3], guid[2], guid[1], guid[0], guid[5], guid[4], guid[7], guid[6], guid[8], guid[9], guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]) + +def ParseGuidString(GuidStr): + # + # Error check and convert C Guid init to string + # ParseGuidString("49152E77-1ADA-4764-B7A2-7AFEFED95E8B") + # ParseGuidString("{ 0xBA24B391, 0x73FD, 0xC54C, { 0x9E, 0xAF, 0x0C, 0xA7, 0x8A, 0x35, 0x46, 0xD1 } }") + # + + if "{" in GuidStr : + # convert C form "{ 0xBA24B391, 0x73FD, 0xC54C, { 0x9E, 0xAF, 0x0C, 0xA7, 0x8A, 0x35, 0x46, 0xD1 } }" + # to string form BA24B391-73FD-C54C-9EAF-0CA78A3546D1 + # make a list of Hex numbers like: ['0xBA24B391', '0x73FD', '0xC54C', '0x9E', '0xAF', '0x0C', '0xA7', '0x8A', '0x35', '0x46', '0xD1'] + Hex = ''.join(x for x in GuidStr if x not in '{,}').split() + Str = "%08X-%04X-%04X-%02.2X%02.2X-%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X" % \ + (int(Hex[0], 0), int(Hex[1], 0), int(Hex[2], 0), int(Hex[3], 0), int(Hex[4], 0), \ + int(Hex[5], 0), int(Hex[6], 0), int(Hex[7], 0), int(Hex[8], 0), int(Hex[9], 0), int(Hex[10], 0)) + elif GuidStr.count('-') == 4: + # validate "49152E77-1ADA-4764-B7A2-7AFEFED95E8B" form + Check = "%s" % str(uuid.UUID(GuidStr)).upper() + if GuidStr.upper() == Check: + Str = GuidStr.upper() + else: + Ste = "" + else: + Str = "" + + return Str + + +def create_guid_options(): + usage = "usage: %prog [data]" + description='''lookup EFI_GUID by CName, C struct, or GUID string and print out all three. + ''' + parser = optparse.OptionParser(description=description, prog='guid',usage=usage) + return parser + +def efi_guid_command(debugger, command, result, dict): + # Use the Shell Lexer to properly parse up command options just like a + # shell would + command_args = shlex.split(command) + parser = create_guid_options() + try: + (options, args) = parser.parse_args(command_args) + if len(args) >= 1: + if args[0] == "{": + # caller forgot to quote the string" + # mark arg[0] a string containing all args[n] + args[0] = ' '.join(args) + GuidStr = ParseGuidString (args[0]) + if GuidStr == "": + # return Key of GuidNameDict for value args[0] + GuidStr = [Key for Key, Value in guid_dict.iteritems() if Value == args[0]][0] + GuidStr = GuidStr.upper() + except: + # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit + # (courtesy of OptParse dealing with argument errors by throwing SystemExit) + result.SetError ("option parsing failed") + return + + + if len(args) >= 1: + if GuidStr in guid_dict: + print "%s = %s" % (guid_dict[GuidStr], GuidStr) + print "%s = %s" % (guid_dict[GuidStr], GuidToCStructStr (GuidStr)) + else: + print GuidStr + else: + # dump entire dictionary + width = max(len(v) for k,v in guid_dict.iteritems()) + for value in sorted(guid_dict, key=guid_dict.get): + print '%-*s %s %s' % (width, guid_dict[value], value, GuidToCStructStr(value)) + + return + + +# +########## Code that runs when this script is imported into LLDB ########### +# +def __lldb_init_module (debugger, internal_dict): + # This initializer is being run from LLDB in the embedded command interpreter + # Make the options so we can generate the help text for the new LLDB + # command line command prior to registering it with LLDB below + + global guid_dict + + # Source Guid.xref file if we can find it + inputfile = os.getcwd() + inputfile += os.sep + os.pardir + os.sep + 'FV' + os.sep + 'Guid.xref' + with open(inputfile) as f: + for line in f: + data = line.split(' ') + if len(data) >= 2: + guid_dict[data[0].upper()] = data[1].strip('\n') + + # init EFI specific type formatters + TypePrintFormating (debugger) + + + # add guid command + parser = create_guid_options() + efi_guid_command.__doc__ = parser.format_help() + debugger.HandleCommand('command script add -f lldbefi.efi_guid_command guid') + + + Target = debugger.GetTargetAtIndex(0) + if Target: + Breakpoint = Target.BreakpointCreateByName('SecGdbScriptBreak') + if Breakpoint.GetNumLocations() == 1: + # Set the emulator breakpoints, if we are in the emulator + debugger.HandleCommand("breakpoint command add -s python -F lldbefi.LoadEmulatorEfiSymbols {id}".format(id=Breakpoint.GetID())) + print 'Type r to run emulator. SecLldbScriptBreak armed. EFI modules should now get source level debugging in the emulator.' diff --git a/CdeEmuPkg/EmulatorPkg/Unix/lldbinit b/CdeEmuPkg/EmulatorPkg/Unix/lldbinit new file mode 100644 index 00000000000..16b34e362b9 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Unix/lldbinit @@ -0,0 +1,3 @@ +setting set frame-format "frame #${frame.index}: ${frame.pc}{ ${module.file.basename}{:${function.name}()${function.pc-offset}}}{ at ${line.file.fullpath}:${line.number}}\n" +command script import lldbefi.py +run diff --git a/CdeEmuPkg/EmulatorPkg/Win/Host/WinBlockIo.c b/CdeEmuPkg/EmulatorPkg/Win/Host/WinBlockIo.c new file mode 100644 index 00000000000..000625fe594 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/Host/WinBlockIo.c @@ -0,0 +1,557 @@ +/**@file + +Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "WinHost.h" + +#define WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE SIGNATURE_32 ('N', 'T', 'b', 'k') +typedef struct { + UINTN Signature; + + EMU_IO_THUNK_PROTOCOL *Thunk; + + CHAR16 *FileName; + BOOLEAN Removable; + BOOLEAN Readonly; + + HANDLE NtHandle; + UINT32 BlockSize; + + EFI_BLOCK_IO_MEDIA *Media; + EMU_BLOCK_IO_PROTOCOL EmuBlockIo; +} WIN_NT_BLOCK_IO_PRIVATE; + +#define WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS(a) \ + CR(a, WIN_NT_BLOCK_IO_PRIVATE, EmuBlockIo, WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE) + + +EFI_STATUS +WinNtBlockIoReset ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ); + + + + +EFI_STATUS +SetFilePointer64 ( + IN WIN_NT_BLOCK_IO_PRIVATE *Private, + IN INT64 DistanceToMove, + OUT UINT64 *NewFilePointer, + IN DWORD MoveMethod +) +/*++ + +This function extends the capability of SetFilePointer to accept 64 bit parameters + +--*/ +{ + EFI_STATUS Status; + LARGE_INTEGER LargeInt; + + LargeInt.QuadPart = DistanceToMove; + Status = EFI_SUCCESS; + + LargeInt.LowPart = SetFilePointer ( + Private->NtHandle, + LargeInt.LowPart, + &LargeInt.HighPart, + MoveMethod + ); + + if (LargeInt.LowPart == -1 && GetLastError () != NO_ERROR) { + Status = EFI_INVALID_PARAMETER; + } + + if (NewFilePointer != NULL) { + *NewFilePointer = LargeInt.QuadPart; + } + + return Status; +} + + + +EFI_STATUS +WinNtBlockIoOpenDevice ( + IN WIN_NT_BLOCK_IO_PRIVATE *Private, + IN EFI_BLOCK_IO_MEDIA *Media + ) +{ + EFI_STATUS Status; + UINT64 FileSize; + + // + // If the device is already opened, close it + // + if (Private->NtHandle != INVALID_HANDLE_VALUE) { + WinNtBlockIoReset (&Private->EmuBlockIo, FALSE); + } + + // + // Open the device + // + Private->NtHandle = CreateFile ( + Private->FileName, + GENERIC_READ | (Private->Readonly ? 0 : GENERIC_WRITE), + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_ALWAYS, // Create if it doesn't exist + 0, + NULL + ); + + if (Private->NtHandle == INVALID_HANDLE_VALUE) { + DEBUG ((EFI_D_INFO, "OpenBlock: Could not open %S, %x\n", Private->FileName, GetLastError ())); + Media->MediaPresent = FALSE; + Status = EFI_NO_MEDIA; + goto Done; + } + + // + // get the size of the file + // + Status = SetFilePointer64 (Private, 0, &FileSize, FILE_END); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "OpenBlock: Could not get filesize of %s\n", Private->FileName)); + Status = EFI_UNSUPPORTED; + goto Done; + } + + Media->LastBlock = DivU64x32 (FileSize, (UINT32)Private->BlockSize) - 1; + + DEBUG ((EFI_D_INIT, "OpenBlock: opened %S\n", Private->FileName)); + Status = EFI_SUCCESS; + +Done: + if (EFI_ERROR (Status)) { + if (Private->NtHandle != INVALID_HANDLE_VALUE) { + WinNtBlockIoReset (&Private->EmuBlockIo, FALSE); + } + } + + return Status; +} + + +EFI_STATUS +EFIAPI +WinNtBlockIoCreateMapping ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN EFI_BLOCK_IO_MEDIA *Media + ) +{ + WIN_NT_BLOCK_IO_PRIVATE *Private; + + Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); + + Media->MediaId = 0; + Media->RemovableMedia = Private->Removable; + Media->MediaPresent = TRUE; + Media->LogicalPartition = FALSE; + Media->ReadOnly = Private->Readonly; + Media->WriteCaching = FALSE; + Media->IoAlign = 1; + Media->LastBlock = 0; // Filled in by OpenDevice + Media->BlockSize = Private->BlockSize; + + // EFI_BLOCK_IO_PROTOCOL_REVISION2 + Media->LowestAlignedLba = 0; + Media->LogicalBlocksPerPhysicalBlock = 0; + + + // EFI_BLOCK_IO_PROTOCOL_REVISION3 + Media->OptimalTransferLengthGranularity = 0; + + // + // Remember the Media pointer. + // + Private->Media = Media; + return WinNtBlockIoOpenDevice (Private, Media); +} + + + +EFI_STATUS +WinNtBlockIoError ( + IN WIN_NT_BLOCK_IO_PRIVATE *Private +) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Private - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +{ + EFI_BLOCK_IO_MEDIA *Media; + EFI_STATUS Status; + + Media = Private->Media; + + switch (GetLastError ()) { + + case ERROR_NOT_READY: + Media->ReadOnly = FALSE; + Media->MediaPresent = FALSE; + Status = EFI_NO_MEDIA; + break; + + case ERROR_WRONG_DISK: + Media->ReadOnly = FALSE; + Media->MediaPresent = TRUE; + Media->MediaId++; + Status = EFI_MEDIA_CHANGED; + break; + + case ERROR_WRITE_PROTECT: + Media->ReadOnly = TRUE; + Status = EFI_WRITE_PROTECTED; + break; + + default: + Status = EFI_DEVICE_ERROR; + break; + } + + if (Status == EFI_NO_MEDIA || Status == EFI_MEDIA_CHANGED) { + WinNtBlockIoReset (&Private->EmuBlockIo, FALSE); + } + + return Status; +} + + +EFI_STATUS +WinNtSignalToken ( + IN OUT EFI_BLOCK_IO2_TOKEN *Token, + IN EFI_STATUS Status +) +{ + if (Token != NULL) { + if (Token->Event != NULL) { + // Caller is responcible for signaling EFI Event + Token->TransactionStatus = Status; + return EFI_SUCCESS; + } + } + 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 +WinNtBlockIoReadBlocks ( + 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 + ) +{ + WIN_NT_BLOCK_IO_PRIVATE *Private; + BOOL Flag; + EFI_STATUS Status; + DWORD BytesRead; + UINT64 DistanceToMove; + UINT64 DistanceMoved; + + Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); + + // + // Seek to proper position + // + DistanceToMove = MultU64x32 (Lba, (UINT32)Private->BlockSize); + Status = SetFilePointer64 (Private, DistanceToMove, &DistanceMoved, FILE_BEGIN); + + if (EFI_ERROR (Status) || (DistanceToMove != DistanceMoved)) { + DEBUG ((EFI_D_INIT, "ReadBlocks: SetFilePointer failed\n")); + return WinNtBlockIoError (Private->Media); + } + + Flag = ReadFile (Private->NtHandle, Buffer, (DWORD)BufferSize, (LPDWORD)&BytesRead, NULL); + if (!Flag || (BytesRead != BufferSize)) { + return WinNtBlockIoError (Private->Media); + } + + Private->Media->MediaPresent = TRUE; + return WinNtSignalToken (Token, EFI_SUCCESS); +} + + +/** + 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_CHANGED The MediaId does not match 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 +WinNtBlockIoWriteBlocks ( + 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 + ) +{ + WIN_NT_BLOCK_IO_PRIVATE *Private; + UINTN BytesWritten; + BOOL Success; + EFI_STATUS Status; + UINT64 DistanceToMove; + UINT64 DistanceMoved; + + Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); + + // + // Seek to proper position + // + DistanceToMove = MultU64x32 (Lba, (UINT32)Private->BlockSize); + Status = SetFilePointer64 (Private, DistanceToMove, &DistanceMoved, FILE_BEGIN); + + if (EFI_ERROR (Status) || (DistanceToMove != DistanceMoved)) { + DEBUG ((EFI_D_INIT, "WriteBlocks: SetFilePointer failed\n")); + return WinNtBlockIoError (Private->Media); + } + + Success = WriteFile (Private->NtHandle, Buffer, (DWORD)BufferSize, (LPDWORD)&BytesWritten, NULL); + if (!Success || (BytesWritten != BufferSize)) { + return WinNtBlockIoError (Private->Media); + } + + // + // If the write succeeded, we are not write protected and media is present. + // + Private->Media->MediaPresent = TRUE; + Private->Media->ReadOnly = FALSE; + return WinNtSignalToken (Token, EFI_SUCCESS); +} + +/** + 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 writing 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 +WinNtBlockIoFlushBlocks ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN OUT EFI_BLOCK_IO2_TOKEN *Token + ) +{ + return WinNtSignalToken (Token, EFI_SUCCESS); +} + + +/** + 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 +WinNtBlockIoReset ( + IN EMU_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + WIN_NT_BLOCK_IO_PRIVATE *Private; + + Private = WIN_NT_BLOCK_IO_PRIVATE_DATA_FROM_THIS (This); + + if (Private->NtHandle != INVALID_HANDLE_VALUE) { + CloseHandle (Private->NtHandle); + Private->NtHandle = INVALID_HANDLE_VALUE; + } + + return EFI_SUCCESS; +} + +EMU_BLOCK_IO_PROTOCOL gEmuBlockIoProtocol = { + WinNtBlockIoReset, + WinNtBlockIoReadBlocks, + WinNtBlockIoWriteBlocks, + WinNtBlockIoFlushBlocks, + WinNtBlockIoCreateMapping +}; + +EFI_STATUS +EFIAPI +WinNtBlockIoThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + WIN_NT_BLOCK_IO_PRIVATE *Private; + CHAR16 *Str; + + Private = AllocatePool (sizeof (*Private)); + if (Private == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Private->Signature = WIN_NT_BLOCK_IO_PRIVATE_SIGNATURE; + Private->Thunk = This; + CopyMem (&Private->EmuBlockIo, &gEmuBlockIoProtocol, sizeof (gEmuBlockIoProtocol)); + Private->BlockSize = 512; + Private->NtHandle = INVALID_HANDLE_VALUE; + + Private->FileName = AllocateCopyPool (StrSize (This->ConfigString), This->ConfigString); + if (Private->FileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // Parse ConfigString + // := ':' [RF][OW] ':' + // + Str = StrStr (Private->FileName, L":"); + if (Str == NULL) { + Private->Removable = FALSE; + Private->Readonly = FALSE; + } else { + for (*Str++ = L'\0'; *Str != L'\0'; Str++) { + if (*Str == 'R' || *Str == 'F') { + Private->Removable = (BOOLEAN) (*Str == L'R'); + } + if (*Str == 'O' || *Str == 'W') { + Private->Readonly = (BOOLEAN) (*Str == L'O'); + } + if (*Str == ':') { + Private->BlockSize = wcstol (++Str, NULL, 0); + break; + } + } + } + + This->Interface = &Private->EmuBlockIo; + This->Private = Private; + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +WinNtBlockIoThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + WIN_NT_BLOCK_IO_PRIVATE *Private; + + Private = This->Private; + + if (Private != NULL) { + if (Private->FileName != NULL) { + FreePool (Private->FileName); + } + FreePool (Private); + } + + return EFI_SUCCESS; +} + + + +EMU_IO_THUNK_PROTOCOL mWinNtBlockIoThunkIo = { + &gEmuBlockIoProtocolGuid, + NULL, + NULL, + 0, + WinNtBlockIoThunkOpen, + WinNtBlockIoThunkClose, + NULL +}; + + diff --git a/CdeEmuPkg/EmulatorPkg/Win/Host/WinFileSystem.c b/CdeEmuPkg/EmulatorPkg/Win/Host/WinFileSystem.c new file mode 100644 index 00000000000..57e00756f3c --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/Host/WinFileSystem.c @@ -0,0 +1,2445 @@ +/*++ @file + Support OS native directory access. + +Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + + +**/ + +#include "WinHost.h" + + +#define WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE SIGNATURE_32 ('N', 'T', 'f', 's') + +typedef struct { + UINTN Signature; + EMU_IO_THUNK_PROTOCOL *Thunk; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystem; + CHAR16 *FilePath; + CHAR16 *VolumeLabel; +} WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE; + +#define WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS(a) \ + CR (a, \ + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE, \ + SimpleFileSystem, \ + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE \ + ) + + +#define WIN_NT_EFI_FILE_PRIVATE_SIGNATURE SIGNATURE_32 ('l', 'o', 'f', 's') + +typedef struct { + UINTN Signature; + EMU_IO_THUNK_PROTOCOL *Thunk; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem; + EFI_FILE_PROTOCOL EfiFile; + HANDLE LHandle; + HANDLE DirHandle; + BOOLEAN IsRootDirectory; + BOOLEAN IsDirectoryPath; + BOOLEAN IsOpenedByRead; + CHAR16 *FilePath; + WCHAR *FileName; + BOOLEAN IsValidFindBuf; + WIN32_FIND_DATA FindBuf; +} WIN_NT_EFI_FILE_PRIVATE; + +#define WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS(a) \ + CR (a, \ + WIN_NT_EFI_FILE_PRIVATE, \ + EfiFile, \ + WIN_NT_EFI_FILE_PRIVATE_SIGNATURE \ + ) + +extern EFI_FILE_PROTOCOL gWinNtFileProtocol; +extern EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gWinNtFileSystemProtocol; + +EFI_STATUS +WinNtFileGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +EFI_STATUS +WinNtFileSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ); + + + +CHAR16 * +EfiStrChr ( + IN CHAR16 *Str, + IN CHAR16 Chr +) +/*++ + +Routine Description: + + Locate the first occurance of a character in a string. + +Arguments: + + Str - Pointer to NULL terminated unicode string. + Chr - Character to locate. + +Returns: + + If Str is NULL, then NULL is returned. + If Chr is not contained in Str, then NULL is returned. + If Chr is contained in Str, then a pointer to the first occurance of Chr in Str is returned. + +--*/ +{ + if (Str == NULL) { + return Str; + } + + while (*Str != '\0' && *Str != Chr) { + ++Str; + } + + return (*Str == Chr) ? Str : NULL; +} + + + +BOOLEAN +IsZero ( + IN VOID *Buffer, + IN UINTN Length + ) +{ + if (Buffer == NULL || Length == 0) { + return FALSE; + } + + if (*(UINT8 *) Buffer != 0) { + return FALSE; + } + + if (Length > 1) { + if (!CompareMem (Buffer, (UINT8 *) Buffer + 1, Length - 1)) { + return FALSE; + } + } + + return TRUE; +} + +VOID +CutPrefix ( + IN CHAR16 *Str, + IN UINTN Count + ) +{ + CHAR16 *Pointer; + + if (StrLen (Str) < Count) { + ASSERT (0); + } + + if (Count != 0) { + for (Pointer = Str; *(Pointer + Count); Pointer++) { + *Pointer = *(Pointer + Count); + } + + *Pointer = *(Pointer + Count); + } +} +/** + 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 +WinNtOpenVolume ( + IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **Root + ) +{ + EFI_STATUS Status; + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + CHAR16 *TempFileName; + UINTN Size; + + if (This == NULL || Root == NULL) { + return EFI_INVALID_PARAMETER; + } + + Private = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (This); + + PrivateFile = AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE)); + if (PrivateFile == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + PrivateFile->FileName = AllocatePool (StrSize (Private->FilePath)); + if (PrivateFile->FileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + PrivateFile->FilePath = AllocatePool (StrSize (Private->FilePath)); + if (PrivateFile->FilePath == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpyS (PrivateFile->FilePath, + StrSize (Private->FilePath) / sizeof (CHAR16), + Private->FilePath + ); + StrCpyS (PrivateFile->FileName, + StrSize (Private->FilePath) / sizeof (CHAR16), + PrivateFile->FilePath + ); + PrivateFile->Signature = WIN_NT_EFI_FILE_PRIVATE_SIGNATURE; + PrivateFile->Thunk = Private->Thunk; + PrivateFile->SimpleFileSystem = This; + PrivateFile->IsRootDirectory = TRUE; + PrivateFile->IsDirectoryPath = TRUE; + PrivateFile->IsOpenedByRead = TRUE; + CopyMem (&PrivateFile->EfiFile, &gWinNtFileProtocol, sizeof (gWinNtFileProtocol)); + PrivateFile->IsValidFindBuf = FALSE; + + // + // Set DirHandle + // + PrivateFile->DirHandle = CreateFile ( + PrivateFile->FilePath, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL + ); + + if (PrivateFile->DirHandle == INVALID_HANDLE_VALUE) { + Status = EFI_NOT_FOUND; + goto Done; + } + + // + // Find the first file under it + // + Size = StrSize (PrivateFile->FilePath); + Size += StrSize (L"\\*"); + TempFileName = AllocatePool (Size); + if (TempFileName == NULL) { + goto Done; + } + StrCpyS (TempFileName, Size / sizeof (CHAR16), PrivateFile->FilePath); + StrCatS (TempFileName, Size / sizeof (CHAR16), L"\\*"); + + PrivateFile->LHandle = FindFirstFile (TempFileName, &PrivateFile->FindBuf); + FreePool (TempFileName); + + if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) { + PrivateFile->IsValidFindBuf = FALSE; + } else { + PrivateFile->IsValidFindBuf = TRUE; + } + *Root = &PrivateFile->EfiFile; + + Status = EFI_SUCCESS; + +Done: + if (EFI_ERROR (Status)) { + if (PrivateFile) { + if (PrivateFile->FileName) { + FreePool (PrivateFile->FileName); + } + + if (PrivateFile->FilePath) { + FreePool (PrivateFile->FilePath); + } + + FreePool (PrivateFile); + } + } + + return Status; +} + +/** + Count the number of Leading Dot in FileNameToken. + + @param FileNameToken A string representing a token in the path name. + + @return UINTN The number of leading dot in the name. + +**/ +UINTN +CountLeadingDots ( + IN CONST CHAR16 * FileNameToken +) +{ + UINTN Num; + + Num = 0; + while (*FileNameToken == L'.') { + Num++; + FileNameToken++; + } + + return Num; +} + + +BOOLEAN +IsFileNameTokenValid ( + IN CONST CHAR16 * FileNameToken +) +{ + UINTN Num; + if (StrStr (FileNameToken, L"/") != NULL) { + // + // No L'/' in file name. + // + return FALSE; + } else { + // + // If Token has all dot, the number should not exceed 2 + // + Num = CountLeadingDots (FileNameToken); + + if (Num == StrLen (FileNameToken)) { + // + // If the FileNameToken only contains a number of L'.'. + // + if (Num > 2) { + return FALSE; + } + } + } + + return TRUE; +} + + +/** + Return the first string token found in the indirect pointer a String named by FileName. + + On input, FileName is a indirect pointer pointing to a String. + On output, FileName is a updated to point to the next character after the first + found L"\" or NULL if there is no L"\" found. + + @param FileName A indirect pointer pointing to a FileName. + + @return Token The first string token found before a L"\". + +**/ +CHAR16 * +GetNextFileNameToken ( + IN OUT CONST CHAR16 ** FileName +) +{ + CHAR16 *SlashPos; + CHAR16 *Token; + UINTN Offset; + ASSERT (**FileName != L'\\'); + ASSERT (**FileName != L'\0'); + + SlashPos = StrStr (*FileName, L"\\"); + if (SlashPos == NULL) { + Token = AllocateCopyPool (StrSize (*FileName), *FileName); + *FileName = NULL; + } else { + Offset = SlashPos - *FileName; + Token = AllocateZeroPool ((Offset + 1) * sizeof (CHAR16)); + StrnCpyS (Token, Offset + 1, *FileName, Offset); + // + // Point *FileName to the next character after L'\'. + // + *FileName = *FileName + Offset + 1; + // + // If *FileName is an empty string, then set *FileName to NULL + // + if (**FileName == L'\0') { + *FileName = NULL; + } + } + + return Token; +} + + +/** + Check if a FileName contains only Valid Characters. + + If FileName contains only a single L'\', return TRUE. + If FileName contains two adjacent L'\', return FALSE. + If FileName conatins L'/' , return FALSE. + If FileName contains more than two dots separated with other FileName characters + by L'\', return FALSE. For example, L'.\...\filename.txt' is invalid path name. But L'..TwoDots\filename.txt' is valid path name. + + @param FileName The File Name String to check. + + @return TRUE FileName only contains valid characters. + @return FALSE FileName contains at least one invalid character. + +**/ + +BOOLEAN +IsFileNameValid ( + IN CONST CHAR16 *FileName + ) +{ + CHAR16 *Token; + BOOLEAN Valid; + + // + // If FileName is just L'\', then it is a valid pathname. + // + if (StrCmp (FileName, L"\\") == 0) { + return TRUE; + } + // + // We don't support two or more adjacent L'\'. + // + if (StrStr (FileName, L"\\\\") != NULL) { + return FALSE; + } + + // + // Is FileName has a leading L"\", skip to next character. + // + if (FileName [0] == L'\\') { + FileName++; + } + + do { + Token = GetNextFileNameToken (&FileName); + Valid = IsFileNameTokenValid (Token); + FreePool (Token); + + if (!Valid) + return FALSE; + } while (FileName != NULL); + + return TRUE; +} + + +/** + 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 +WinNtFileOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + WIN_NT_EFI_FILE_PRIVATE *NewPrivateFile; + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot; + EFI_STATUS Status; + CHAR16 *RealFileName; + CHAR16 *TempFileName; + CHAR16 *ParseFileName; + CHAR16 *GuardPointer; + CHAR16 TempChar; + DWORD LastError; + UINTN Count; + BOOLEAN LoopFinish; + UINTN InfoSize; + EFI_FILE_INFO *Info; + UINTN Size; + + + // + // Init local variables + // + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem); + NewPrivateFile = NULL; + + // + // Allocate buffer for FileName as the passed in FileName may be read only + // + TempFileName = AllocatePool (StrSize (FileName)); + if (TempFileName == NULL) { + return EFI_OUT_OF_RESOURCES; + } + StrCpyS (TempFileName, StrSize (FileName) / sizeof (CHAR16), FileName); + FileName = TempFileName; + + if (FileName[StrLen (FileName) - 1] == L'\\') { + FileName[StrLen (FileName) - 1] = 0; + } + + // + // If file name does not equal to "." or ".." and not trailed with "\..", + // then we trim the leading/trailing blanks and trailing dots + // + if (StrCmp (FileName, L".") != 0 && StrCmp (FileName, L"..") != 0 && + ((StrLen (FileName) >= 3) ? (StrCmp (&FileName[StrLen (FileName) - 3], L"\\..") != 0) : TRUE)) { + // + // Trim leading blanks + // + Count = 0; + for (TempFileName = FileName; + *TempFileName != 0 && *TempFileName == L' '; + TempFileName++) { + Count++; + } + CutPrefix (FileName, Count); + // + // Trim trailing blanks + // + for (TempFileName = FileName + StrLen (FileName) - 1; + TempFileName >= FileName && (*TempFileName == L' '); + TempFileName--) { + ; + } + *(TempFileName + 1) = 0; + } + + // + // Attempt to open the file + // + NewPrivateFile = AllocatePool (sizeof (WIN_NT_EFI_FILE_PRIVATE)); + if (NewPrivateFile == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + CopyMem (NewPrivateFile, PrivateFile, sizeof (WIN_NT_EFI_FILE_PRIVATE)); + + NewPrivateFile->FilePath = AllocatePool (StrSize (PrivateFile->FileName)); + if (NewPrivateFile->FilePath == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + if (PrivateFile->IsDirectoryPath) { + StrCpyS ( + NewPrivateFile->FilePath, + StrSize (PrivateFile->FileName) / sizeof (CHAR16), + PrivateFile->FileName + ); + } else { + StrCpyS ( + NewPrivateFile->FilePath, + StrSize (PrivateFile->FileName) / sizeof (CHAR16), + PrivateFile->FilePath + ); + } + + Size = StrSize (NewPrivateFile->FilePath); + Size += StrSize (L"\\"); + Size += StrSize (FileName); + NewPrivateFile->FileName = AllocatePool (Size); + if (NewPrivateFile->FileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + if (*FileName == L'\\') { + StrCpyS (NewPrivateFile->FileName, Size / sizeof (CHAR16), PrivateRoot->FilePath); + StrCatS (NewPrivateFile->FileName, Size / sizeof (CHAR16), L"\\"); + StrCatS (NewPrivateFile->FileName, Size / sizeof (CHAR16), FileName + 1); + } else { + StrCpyS (NewPrivateFile->FileName, Size / sizeof (CHAR16), NewPrivateFile->FilePath); + if (StrCmp (FileName, L"") != 0) { + // + // In case the filename becomes empty, especially after trimming dots and blanks + // + StrCatS (NewPrivateFile->FileName, Size / sizeof (CHAR16), L"\\"); + StrCatS (NewPrivateFile->FileName, Size / sizeof (CHAR16), FileName); + } + } + + if (!IsFileNameValid (NewPrivateFile->FileName)) { + Status = EFI_NOT_FOUND; + goto Done; + } + + // + // Get rid of . and .., except leading . or .. + // + + // + // GuardPointer protect simplefilesystem root path not be destroyed + // + GuardPointer = NewPrivateFile->FileName + StrLen (PrivateRoot->FilePath); + + LoopFinish = FALSE; + + while (!LoopFinish) { + + LoopFinish = TRUE; + + for (ParseFileName = GuardPointer; *ParseFileName; ParseFileName++) { + if (*ParseFileName == L'.' && + (*(ParseFileName + 1) == 0 || *(ParseFileName + 1) == L'\\') && + *(ParseFileName - 1) == L'\\' + ) { + + // + // cut \. + // + CutPrefix (ParseFileName - 1, 2); + LoopFinish = FALSE; + break; + } + + if (*ParseFileName == L'.' && + *(ParseFileName + 1) == L'.' && + (*(ParseFileName + 2) == 0 || *(ParseFileName + 2) == L'\\') && + *(ParseFileName - 1) == L'\\' + ) { + + ParseFileName--; + Count = 3; + + while (ParseFileName != GuardPointer) { + ParseFileName--; + Count++; + if (*ParseFileName == L'\\') { + break; + } + } + + // + // cut \.. and its left directory + // + CutPrefix (ParseFileName, Count); + LoopFinish = FALSE; + break; + } + } + } + + RealFileName = NewPrivateFile->FileName; + while (EfiStrChr (RealFileName, L'\\') != NULL) { + RealFileName = EfiStrChr (RealFileName, L'\\') + 1; + } + + TempChar = 0; + if (RealFileName != NewPrivateFile->FileName) { + TempChar = *(RealFileName - 1); + *(RealFileName - 1) = 0; + } + + FreePool (NewPrivateFile->FilePath); + NewPrivateFile->FilePath = NULL; + NewPrivateFile->FilePath = AllocatePool (StrSize (NewPrivateFile->FileName)); + if (NewPrivateFile->FilePath == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpyS ( + NewPrivateFile->FilePath, + StrSize (NewPrivateFile->FileName) / sizeof (CHAR16), + NewPrivateFile->FileName + ); + if (TempChar != 0) { + *(RealFileName - 1) = TempChar; + } + + NewPrivateFile->IsRootDirectory = FALSE; + + // + // Test whether file or directory + // + if (OpenMode & EFI_FILE_MODE_CREATE) { + if (Attributes & EFI_FILE_DIRECTORY) { + NewPrivateFile->IsDirectoryPath = TRUE; + } else { + NewPrivateFile->IsDirectoryPath = FALSE; + } + } else { + NewPrivateFile->LHandle = CreateFile ( + NewPrivateFile->FileName, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + + if (NewPrivateFile->LHandle != INVALID_HANDLE_VALUE) { + NewPrivateFile->IsDirectoryPath = FALSE; + CloseHandle (NewPrivateFile->LHandle); + } else { + NewPrivateFile->IsDirectoryPath = TRUE; + } + + NewPrivateFile->LHandle = INVALID_HANDLE_VALUE; + } + + if (OpenMode & EFI_FILE_MODE_WRITE) { + NewPrivateFile->IsOpenedByRead = FALSE; + } else { + NewPrivateFile->IsOpenedByRead = TRUE; + } + + Status = EFI_SUCCESS; + + // + // deal with directory + // + if (NewPrivateFile->IsDirectoryPath) { + + Size = StrSize (NewPrivateFile->FileName); + Size += StrSize (L"\\*"); + TempFileName = AllocatePool (Size); + if (TempFileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpyS (TempFileName, Size / sizeof (CHAR16), NewPrivateFile->FileName); + + if ((OpenMode & EFI_FILE_MODE_CREATE)) { + // + // Create a directory + // + if (!CreateDirectory (TempFileName, NULL)) { + + LastError = GetLastError (); + if (LastError != ERROR_ALREADY_EXISTS) { + FreePool (TempFileName); + Status = EFI_ACCESS_DENIED; + goto Done; + } + } + } + + NewPrivateFile->DirHandle = CreateFile ( + TempFileName, + NewPrivateFile->IsOpenedByRead ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE), + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL + ); + + if (NewPrivateFile->DirHandle == INVALID_HANDLE_VALUE) { + + NewPrivateFile->DirHandle = CreateFile ( + TempFileName, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL + ); + + if (NewPrivateFile->DirHandle != INVALID_HANDLE_VALUE) { + CloseHandle (NewPrivateFile->DirHandle); + NewPrivateFile->DirHandle = INVALID_HANDLE_VALUE; + Status = EFI_ACCESS_DENIED; + } else { + Status = EFI_NOT_FOUND; + } + + FreePool (TempFileName); + goto Done; + } + + // + // Find the first file under it + // + StrCatS (TempFileName, Size / sizeof (CHAR16), L"\\*"); + NewPrivateFile->LHandle = FindFirstFile (TempFileName, &NewPrivateFile->FindBuf); + FreePool (TempFileName); + + if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) { + NewPrivateFile->IsValidFindBuf = FALSE; + } else { + NewPrivateFile->IsValidFindBuf = TRUE; + } + } else { + // + // deal with file + // + if (!NewPrivateFile->IsOpenedByRead) { + NewPrivateFile->LHandle = CreateFile ( + NewPrivateFile->FileName, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + (OpenMode & EFI_FILE_MODE_CREATE) ? OPEN_ALWAYS : OPEN_EXISTING, + 0, + NULL + ); + + if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) { + NewPrivateFile->LHandle = CreateFile ( + NewPrivateFile->FileName, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + + if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) { + Status = EFI_NOT_FOUND; + } else { + Status = EFI_ACCESS_DENIED; + CloseHandle (NewPrivateFile->LHandle); + NewPrivateFile->LHandle = INVALID_HANDLE_VALUE; + } + } + } else { + NewPrivateFile->LHandle = CreateFile ( + NewPrivateFile->FileName, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + + if (NewPrivateFile->LHandle == INVALID_HANDLE_VALUE) { + Status = EFI_NOT_FOUND; + } + } + } + + if ((OpenMode & EFI_FILE_MODE_CREATE) && Status == EFI_SUCCESS) { + // + // Set the attribute + // + InfoSize = 0; + Info = NULL; + + Status = WinNtFileGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info); + + if (Status != EFI_BUFFER_TOO_SMALL) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + Info = AllocatePool (InfoSize); + if (Info == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + Status = WinNtFileGetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, &InfoSize, Info); + + if (EFI_ERROR (Status)) { + FreePool (Info); + goto Done; + } + + Info->Attribute = Attributes; + + WinNtFileSetInfo (&NewPrivateFile->EfiFile, &gEfiFileInfoGuid, InfoSize, Info); + FreePool (Info); + } + +Done: + FreePool (FileName); + + if (EFI_ERROR (Status)) { + if (NewPrivateFile) { + if (NewPrivateFile->FileName) { + FreePool (NewPrivateFile->FileName); + } + + if (NewPrivateFile->FilePath) { + FreePool (NewPrivateFile->FilePath); + } + + FreePool (NewPrivateFile); + } + } else { + *NewHandle = &NewPrivateFile->EfiFile; + if (StrCmp (NewPrivateFile->FileName, PrivateRoot->FilePath) == 0) { + NewPrivateFile->IsRootDirectory = TRUE; + } + } + + return Status; +} + + + +/** + Close the file handle + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The device was opened. + +**/ +EFI_STATUS +WinNtFileClose ( + IN EFI_FILE_PROTOCOL *This + ) +{ + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) { + if (PrivateFile->IsDirectoryPath) { + FindClose (PrivateFile->LHandle); + } else { + CloseHandle (PrivateFile->LHandle); + } + + PrivateFile->LHandle = INVALID_HANDLE_VALUE; + } + + if (PrivateFile->IsDirectoryPath && PrivateFile->DirHandle != INVALID_HANDLE_VALUE) { + CloseHandle (PrivateFile->DirHandle); + PrivateFile->DirHandle = INVALID_HANDLE_VALUE; + } + + if (PrivateFile->FileName) { + FreePool (PrivateFile->FileName); + } + + if (PrivateFile->FilePath) { + FreePool (PrivateFile->FilePath); + } + + FreePool (PrivateFile); + + return EFI_SUCCESS; + +} + + +/** + Close and delete the file handle. + + @param This Protocol instance pointer. + + @retval EFI_SUCCESS The device was opened. + @retval EFI_WARN_DELETE_FAILURE The handle was closed but the file was not deleted. + +**/ +EFI_STATUS +WinNtFileDelete ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EFI_STATUS Status; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + Status = EFI_WARN_DELETE_FAILURE; + + if (PrivateFile->IsDirectoryPath) { + if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) { + FindClose (PrivateFile->LHandle); + } + + if (PrivateFile->DirHandle != INVALID_HANDLE_VALUE) { + CloseHandle (PrivateFile->DirHandle); + PrivateFile->DirHandle = INVALID_HANDLE_VALUE; + } + + if (RemoveDirectory (PrivateFile->FileName)) { + Status = EFI_SUCCESS; + } + } else { + CloseHandle (PrivateFile->LHandle); + PrivateFile->LHandle = INVALID_HANDLE_VALUE; + + if (!PrivateFile->IsOpenedByRead) { + if (DeleteFile (PrivateFile->FileName)) { + Status = EFI_SUCCESS; + } + } + } + + FreePool (PrivateFile->FileName); + FreePool (PrivateFile->FilePath); + FreePool (PrivateFile); + + return Status; +} + +VOID +WinNtSystemTimeToEfiTime ( + IN SYSTEMTIME *SystemTime, + IN TIME_ZONE_INFORMATION *TimeZone, + OUT EFI_TIME *Time +) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + SystemTime - TODO: add argument description + TimeZone - TODO: add argument description + Time - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +{ + Time->Year = (UINT16)SystemTime->wYear; + Time->Month = (UINT8)SystemTime->wMonth; + Time->Day = (UINT8)SystemTime->wDay; + Time->Hour = (UINT8)SystemTime->wHour; + Time->Minute = (UINT8)SystemTime->wMinute; + Time->Second = (UINT8)SystemTime->wSecond; + Time->Nanosecond = (UINT32)SystemTime->wMilliseconds * 1000000; + Time->TimeZone = (INT16)TimeZone->Bias; + + if (TimeZone->StandardDate.wMonth) { + Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT; + } +} + +/** + Convert the FileTime to EfiTime. + + @param PrivateFile Pointer to WIN_NT_EFI_FILE_PRIVATE. + @param TimeZone Pointer to the current time zone. + @param FileTime Pointer to file time. + @param EfiTime Pointer to EFI time. +**/ +VOID +WinNtFileTimeToEfiTime ( + IN CONST WIN_NT_EFI_FILE_PRIVATE *PrivateFile, + IN TIME_ZONE_INFORMATION *TimeZone, + IN CONST FILETIME *FileTime, + OUT EFI_TIME *EfiTime +) +{ + FILETIME TempFileTime; + SYSTEMTIME SystemTime; + + FileTimeToLocalFileTime (FileTime, &TempFileTime); + FileTimeToSystemTime (&TempFileTime, &SystemTime); + WinNtSystemTimeToEfiTime (&SystemTime, TimeZone, EfiTime); +} + + +/** + 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 +WinNtFileRead ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + EFI_STATUS Status; + UINTN Size; + UINTN NameSize; + UINTN ResultSize; + UINTN Index; + EFI_FILE_INFO *Info; + WCHAR *pw; + TIME_ZONE_INFORMATION TimeZone; + EFI_FILE_INFO *FileInfo; + UINT64 Pos; + UINT64 FileSize; + UINTN FileInfoSize; + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + if (!PrivateFile->IsDirectoryPath) { + + if (This->GetPosition (This, &Pos) != EFI_SUCCESS) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + FileInfoSize = SIZE_OF_EFI_FILE_SYSTEM_INFO; + FileInfo = AllocatePool (FileInfoSize); + + Status = This->GetInfo ( + This, + &gEfiFileInfoGuid, + &FileInfoSize, + FileInfo + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + FreePool (FileInfo); + FileInfo = AllocatePool (FileInfoSize); + Status = This->GetInfo ( + This, + &gEfiFileInfoGuid, + &FileInfoSize, + FileInfo + ); + } + + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + FileSize = FileInfo->FileSize; + + FreePool (FileInfo); + + if (Pos >= FileSize) { + *BufferSize = 0; + if (Pos == FileSize) { + Status = EFI_SUCCESS; + goto Done; + } else { + Status = EFI_DEVICE_ERROR; + goto Done; + } + } + + Status = ReadFile ( + PrivateFile->LHandle, + Buffer, + (DWORD)*BufferSize, + (LPDWORD)BufferSize, + NULL + ) ? EFI_SUCCESS : EFI_DEVICE_ERROR; + goto Done; + } + + // + // Read on a directory. Perform a find next + // + if (!PrivateFile->IsValidFindBuf) { + *BufferSize = 0; + Status = EFI_SUCCESS; + goto Done; + } + + Size = SIZE_OF_EFI_FILE_INFO; + + NameSize = StrSize (PrivateFile->FindBuf.cFileName); + + ResultSize = Size + NameSize; + + Status = EFI_BUFFER_TOO_SMALL; + + if (*BufferSize >= ResultSize) { + Status = EFI_SUCCESS; + + Info = Buffer; + ZeroMem (Info, ResultSize); + + Info->Size = ResultSize; + + GetTimeZoneInformation (&TimeZone); + WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &PrivateFile->FindBuf.ftCreationTime, &Info->CreateTime); + WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &PrivateFile->FindBuf.ftLastAccessTime, &Info->LastAccessTime); + WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &PrivateFile->FindBuf.ftLastWriteTime, &Info->ModificationTime); + + Info->FileSize = PrivateFile->FindBuf.nFileSizeLow; + + Info->PhysicalSize = PrivateFile->FindBuf.nFileSizeLow; + + if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) { + Info->Attribute |= EFI_FILE_ARCHIVE; + } + + if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) { + Info->Attribute |= EFI_FILE_HIDDEN; + } + + if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) { + Info->Attribute |= EFI_FILE_SYSTEM; + } + + if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { + Info->Attribute |= EFI_FILE_READ_ONLY; + } + + if (PrivateFile->FindBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + Info->Attribute |= EFI_FILE_DIRECTORY; + } + + NameSize = NameSize / sizeof (WCHAR); + + pw = (WCHAR *)(((CHAR8 *)Buffer) + Size); + + for (Index = 0; Index < NameSize; Index++) { + pw[Index] = PrivateFile->FindBuf.cFileName[Index]; + } + + if (FindNextFile (PrivateFile->LHandle, &PrivateFile->FindBuf)) { + PrivateFile->IsValidFindBuf = TRUE; + } else { + PrivateFile->IsValidFindBuf = FALSE; + } + } + + *BufferSize = ResultSize; + +Done: + 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 +WinNtFileWrite ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +{ + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + EFI_STATUS Status; + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + if (PrivateFile->IsDirectoryPath) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + if (PrivateFile->IsOpenedByRead) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + Status = WriteFile ( + PrivateFile->LHandle, + Buffer, + (DWORD)*BufferSize, + (LPDWORD)BufferSize, + NULL + ) ? EFI_SUCCESS : EFI_DEVICE_ERROR; + +Done: + return Status; + + // + // bugbug: need to access windows error reporting + // +} + + + +/** + Set a files current position + + @param This Protocol instance pointer. + @param Position Byte position from the start of the file. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open. + +**/ +EFI_STATUS +WinNtFileSetPossition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ) +{ + EFI_STATUS Status; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + UINT32 PosLow; + UINT32 PosHigh; + CHAR16 *FileName; + UINTN Size; + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->IsDirectoryPath) { + if (Position != 0) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + Size = StrSize (PrivateFile->FileName); + Size += StrSize (L"\\*"); + FileName = AllocatePool (Size); + if (FileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpyS (FileName, Size / sizeof (CHAR16), PrivateFile->FileName); + StrCatS (FileName, Size / sizeof (CHAR16), L"\\*"); + + if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) { + FindClose (PrivateFile->LHandle); + } + + PrivateFile->LHandle = FindFirstFile (FileName, &PrivateFile->FindBuf); + + if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) { + PrivateFile->IsValidFindBuf = FALSE; + } else { + PrivateFile->IsValidFindBuf = TRUE; + } + + FreePool (FileName); + + Status = (PrivateFile->LHandle == INVALID_HANDLE_VALUE) ? EFI_DEVICE_ERROR : EFI_SUCCESS; + } else { + if (Position == (UINT64)-1) { + PosLow = SetFilePointer (PrivateFile->LHandle, (ULONG)0, NULL, FILE_END); + } else { + PosHigh = (UINT32)RShiftU64 (Position, 32); + + PosLow = SetFilePointer (PrivateFile->LHandle, (ULONG)Position, (PLONG)&PosHigh, FILE_BEGIN); + } + + Status = (PosLow == 0xFFFFFFFF) ? EFI_DEVICE_ERROR : EFI_SUCCESS; + } + +Done: + 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 Data was written. + @retval EFI_UNSUPPORTED Seek request for non-zero is not valid on open.. + +**/ +EFI_STATUS +WinNtFileGetPossition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ) +{ + EFI_STATUS Status; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + INT32 PositionHigh; + UINT64 PosHigh64; + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + PositionHigh = 0; + PosHigh64 = 0; + + if (PrivateFile->IsDirectoryPath) { + + Status = EFI_UNSUPPORTED; + goto Done; + + } else { + + PositionHigh = 0; + *Position = SetFilePointer ( + PrivateFile->LHandle, + 0, + (PLONG)&PositionHigh, + FILE_CURRENT + ); + + Status = *Position == 0xffffffff ? EFI_DEVICE_ERROR : EFI_SUCCESS; + if (EFI_ERROR (Status)) { + goto Done; + } + + PosHigh64 = PositionHigh; + *Position += LShiftU64 (PosHigh64, 32); + } + +Done: + return Status; +} + + +EFI_STATUS +WinNtSimpleFileSystemFileInfo ( + IN WIN_NT_EFI_FILE_PRIVATE *PrivateFile, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer +) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + PrivateFile - TODO: add argument description + BufferSize - TODO: add argument description + Buffer - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +{ + EFI_STATUS Status; + UINTN Size; + UINTN NameSize; + UINTN ResultSize; + EFI_FILE_INFO *Info; + BY_HANDLE_FILE_INFORMATION FileInfo; + CHAR16 *RealFileName; + CHAR16 *TempPointer; + TIME_ZONE_INFORMATION TimeZone; + + Size = SIZE_OF_EFI_FILE_INFO; + + RealFileName = PrivateFile->FileName; + TempPointer = RealFileName; + while (*TempPointer) { + if (*TempPointer == '\\') { + RealFileName = TempPointer + 1; + } + + TempPointer++; + } + NameSize = StrSize (RealFileName); + + ResultSize = Size + NameSize; + + Status = EFI_BUFFER_TOO_SMALL; + if (*BufferSize >= ResultSize) { + Status = EFI_SUCCESS; + + Info = Buffer; + ZeroMem (Info, ResultSize); + + Info->Size = ResultSize; + GetFileInformationByHandle ( + PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle, + &FileInfo + ); + Info->FileSize = FileInfo.nFileSizeLow; + Info->PhysicalSize = Info->FileSize; + + GetTimeZoneInformation (&TimeZone); + WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &FileInfo.ftCreationTime, &Info->CreateTime); + WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &FileInfo.ftLastAccessTime, &Info->LastAccessTime); + WinNtFileTimeToEfiTime (PrivateFile, &TimeZone, &FileInfo.ftLastWriteTime, &Info->ModificationTime); + + if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) { + Info->Attribute |= EFI_FILE_ARCHIVE; + } + + if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) { + Info->Attribute |= EFI_FILE_HIDDEN; + } + + if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { + Info->Attribute |= EFI_FILE_READ_ONLY; + } + + if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) { + Info->Attribute |= EFI_FILE_SYSTEM; + } + + if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + Info->Attribute |= EFI_FILE_DIRECTORY; + } + + if (PrivateFile->IsDirectoryPath) { + Info->Attribute |= EFI_FILE_DIRECTORY; + } + + if (PrivateFile->IsRootDirectory) { + *((CHAR8 *)Buffer + Size) = 0; + } else { + CopyMem ((CHAR8 *)Buffer + Size, RealFileName, NameSize); + } + } + + *BufferSize = ResultSize; + 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 +WinNtFileGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + EFI_STATUS Status; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + EFI_FILE_SYSTEM_INFO *FileSystemInfoBuffer; + UINT32 SectorsPerCluster; + UINT32 BytesPerSector; + UINT32 FreeClusters; + UINT32 TotalClusters; + UINT32 BytesPerCluster; + CHAR16 *DriveName; + BOOLEAN DriveNameFound; + BOOL NtStatus; + UINTN Index; + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot; + + if (This == NULL || InformationType == NULL || BufferSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem); + + Status = EFI_UNSUPPORTED; + + if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { + Status = WinNtSimpleFileSystemFileInfo (PrivateFile, BufferSize, Buffer); + } + + if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { + if (*BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel)) { + *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); + Status = EFI_BUFFER_TOO_SMALL; + goto Done; + } + + FileSystemInfoBuffer = (EFI_FILE_SYSTEM_INFO *)Buffer; + FileSystemInfoBuffer->Size = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); + FileSystemInfoBuffer->ReadOnly = FALSE; + + // + // Try to get the drive name + // + DriveNameFound = FALSE; + DriveName = AllocatePool (StrSize (PrivateFile->FilePath) + 1); + if (DriveName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpyS ( + DriveName, + (StrSize (PrivateFile->FilePath) + 1) / sizeof (CHAR16), + PrivateFile->FilePath + ); + for (Index = 0; DriveName[Index] != 0 && DriveName[Index] != ':'; Index++) { + ; + } + + if (DriveName[Index] == ':') { + DriveName[Index + 1] = '\\'; + DriveName[Index + 2] = 0; + DriveNameFound = TRUE; + } else if (DriveName[0] == '\\' && DriveName[1] == '\\') { + for (Index = 2; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) { + ; + } + + if (DriveName[Index] == '\\') { + DriveNameFound = TRUE; + for (Index++; DriveName[Index] != 0 && DriveName[Index] != '\\'; Index++) { + ; + } + + DriveName[Index] = '\\'; + DriveName[Index + 1] = 0; + } + } + + // + // Try GetDiskFreeSpace first + // + NtStatus = GetDiskFreeSpace ( + DriveNameFound ? DriveName : NULL, + (LPDWORD)&SectorsPerCluster, + (LPDWORD)&BytesPerSector, + (LPDWORD)&FreeClusters, + (LPDWORD)&TotalClusters + ); + if (DriveName) { + FreePool (DriveName); + } + + if (NtStatus) { + // + // Succeeded + // + BytesPerCluster = BytesPerSector * SectorsPerCluster; + FileSystemInfoBuffer->VolumeSize = MultU64x32 (TotalClusters, BytesPerCluster); + FileSystemInfoBuffer->FreeSpace = MultU64x32 (FreeClusters, BytesPerCluster); + FileSystemInfoBuffer->BlockSize = BytesPerCluster; + + } else { + // + // try GetDiskFreeSpaceEx then + // + FileSystemInfoBuffer->BlockSize = 0; + NtStatus = GetDiskFreeSpaceEx ( + PrivateFile->FilePath, + (PULARGE_INTEGER)(&FileSystemInfoBuffer->FreeSpace), + (PULARGE_INTEGER)(&FileSystemInfoBuffer->VolumeSize), + NULL + ); + if (!NtStatus) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + } + + StrCpyS ( + (CHAR16 *)FileSystemInfoBuffer->VolumeLabel, + (*BufferSize - SIZE_OF_EFI_FILE_SYSTEM_INFO) / sizeof (CHAR16), + PrivateRoot->VolumeLabel + ); + *BufferSize = SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (PrivateRoot->VolumeLabel); + Status = EFI_SUCCESS; + } + + if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { + if (*BufferSize < StrSize (PrivateRoot->VolumeLabel)) { + *BufferSize = StrSize (PrivateRoot->VolumeLabel); + Status = EFI_BUFFER_TOO_SMALL; + goto Done; + } + + StrCpyS ( + (CHAR16 *)Buffer, + *BufferSize / sizeof (CHAR16), + PrivateRoot->VolumeLabel + ); + *BufferSize = StrSize (PrivateRoot->VolumeLabel); + Status = EFI_SUCCESS; + } + +Done: + 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 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. + +**/ +EFI_STATUS +WinNtFileSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *PrivateRoot; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + EFI_FILE_INFO *OldFileInfo; + EFI_FILE_INFO *NewFileInfo; + EFI_STATUS Status; + UINTN OldInfoSize; + INTN NtStatus; + UINT32 NewAttr; + UINT32 OldAttr; + CHAR16 *OldFileName; + CHAR16 *NewFileName; + CHAR16 *TempFileName; + CHAR16 *CharPointer; + BOOLEAN AttrChangeFlag; + BOOLEAN NameChangeFlag; + BOOLEAN SizeChangeFlag; + BOOLEAN TimeChangeFlag; + UINT64 CurPos; + SYSTEMTIME NewCreationSystemTime; + SYSTEMTIME NewLastAccessSystemTime; + SYSTEMTIME NewLastWriteSystemTime; + FILETIME NewCreationFileTime; + FILETIME NewLastAccessFileTime; + FILETIME NewLastWriteFileTime; + WIN32_FIND_DATA FindBuf; + EFI_FILE_SYSTEM_INFO *NewFileSystemInfo; + UINTN Size; + + // + // Initialise locals. + // + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + PrivateRoot = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_DATA_FROM_THIS (PrivateFile->SimpleFileSystem); + + Status = EFI_UNSUPPORTED; + OldFileInfo = NewFileInfo = NULL; + OldFileName = NewFileName = NULL; + AttrChangeFlag = NameChangeFlag = SizeChangeFlag = TimeChangeFlag = FALSE; + + // + // Set file system information. + // + if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { + NewFileSystemInfo = (EFI_FILE_SYSTEM_INFO *)Buffer; + if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (NewFileSystemInfo->VolumeLabel)) { + Status = EFI_BAD_BUFFER_SIZE; + goto Done; + } + + + FreePool (PrivateRoot->VolumeLabel); + PrivateRoot->VolumeLabel = AllocatePool (StrSize (NewFileSystemInfo->VolumeLabel)); + if (PrivateRoot->VolumeLabel == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpyS ( + PrivateRoot->VolumeLabel, + StrSize (NewFileSystemInfo->VolumeLabel) / sizeof (CHAR16), + NewFileSystemInfo->VolumeLabel + ); + + Status = EFI_SUCCESS; + goto Done; + } + + // + // Set volume label information. + // + if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { + if (BufferSize < StrSize (PrivateRoot->VolumeLabel)) { + Status = EFI_BAD_BUFFER_SIZE; + goto Done; + } + + StrCpyS ( + PrivateRoot->VolumeLabel, + StrSize (PrivateRoot->VolumeLabel) / sizeof (CHAR16), + (CHAR16 *)Buffer + ); + + Status = EFI_SUCCESS; + goto Done; + } + + if (!CompareGuid (InformationType, &gEfiFileInfoGuid)) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + if (BufferSize < SIZE_OF_EFI_FILE_INFO) { + Status = EFI_BAD_BUFFER_SIZE; + goto Done; + } + + // + // Set file/directory information. + // + + // + // Check for invalid set file information parameters. + // + NewFileInfo = (EFI_FILE_INFO *)Buffer; + + if ((NewFileInfo->Size <= SIZE_OF_EFI_FILE_INFO) || + (NewFileInfo->Attribute &~(EFI_FILE_VALID_ATTR)) || + (sizeof (UINTN) == 4 && NewFileInfo->Size > 0xFFFFFFFF) + ) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + // + // bugbug: - This is not safe. We need something like EfiStrMaxSize() + // that would have an additional parameter that would be the size + // of the string array just in case there are no NULL characters in + // the string array. + // + // + // Get current file information so we can determine what kind + // of change request this is. + // + OldInfoSize = 0; + Status = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, NULL); + + if (Status != EFI_BUFFER_TOO_SMALL) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + OldFileInfo = AllocatePool (OldInfoSize); + if (OldFileInfo == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + Status = WinNtSimpleFileSystemFileInfo (PrivateFile, &OldInfoSize, OldFileInfo); + + if (EFI_ERROR (Status)) { + goto Done; + } + + OldFileName = AllocatePool (StrSize (PrivateFile->FileName)); + if (OldFileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpyS ( + OldFileName, + StrSize (PrivateFile->FileName) / sizeof (CHAR16), + PrivateFile->FileName + ); + + // + // Make full pathname from new filename and rootpath. + // + if (NewFileInfo->FileName[0] == '\\') { + Size = StrSize (PrivateRoot->FilePath); + Size += StrSize (L"\\"); + Size += StrSize (NewFileInfo->FileName); + NewFileName = AllocatePool (Size); + if (NewFileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpyS (NewFileName, Size / sizeof (CHAR16), PrivateRoot->FilePath); + StrCatS (NewFileName, Size / sizeof (CHAR16), L"\\"); + StrCatS (NewFileName, Size / sizeof (CHAR16), NewFileInfo->FileName + 1); + } else { + Size = StrSize (PrivateFile->FilePath); + Size += StrSize (L"\\"); + Size += StrSize (NewFileInfo->FileName); + NewFileName = AllocatePool (Size); + if (NewFileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpyS (NewFileName, Size / sizeof (CHAR16), PrivateFile->FilePath); + StrCatS (NewFileName, Size / sizeof (CHAR16), L"\\"); + StrCatS (NewFileName, Size / sizeof (CHAR16), NewFileInfo->FileName); + } + + // + // Is there an attribute change request? + // + if (NewFileInfo->Attribute != OldFileInfo->Attribute) { + if ((NewFileInfo->Attribute & EFI_FILE_DIRECTORY) != (OldFileInfo->Attribute & EFI_FILE_DIRECTORY)) { + Status = EFI_INVALID_PARAMETER; + goto Done; + } + + AttrChangeFlag = TRUE; + } + + // + // Is there a name change request? + // bugbug: - Need EfiStrCaseCmp() + // + if (StrCmp (NewFileInfo->FileName, OldFileInfo->FileName)) { + NameChangeFlag = TRUE; + } + + // + // Is there a size change request? + // + if (NewFileInfo->FileSize != OldFileInfo->FileSize) { + SizeChangeFlag = TRUE; + } + + // + // Is there a time stamp change request? + // + if (!IsZero (&NewFileInfo->CreateTime, sizeof (EFI_TIME)) && + CompareMem (&NewFileInfo->CreateTime, &OldFileInfo->CreateTime, sizeof (EFI_TIME)) + ) { + TimeChangeFlag = TRUE; + } else if (!IsZero (&NewFileInfo->LastAccessTime, sizeof (EFI_TIME)) && + CompareMem (&NewFileInfo->LastAccessTime, &OldFileInfo->LastAccessTime, sizeof (EFI_TIME)) + ) { + TimeChangeFlag = TRUE; + } else if (!IsZero (&NewFileInfo->ModificationTime, sizeof (EFI_TIME)) && + CompareMem (&NewFileInfo->ModificationTime, &OldFileInfo->ModificationTime, sizeof (EFI_TIME)) + ) { + TimeChangeFlag = TRUE; + } + + // + // All done if there are no change requests being made. + // + if (!(AttrChangeFlag || NameChangeFlag || SizeChangeFlag || TimeChangeFlag)) { + Status = EFI_SUCCESS; + goto Done; + } + + // + // Set file or directory information. + // + OldAttr = GetFileAttributes (OldFileName); + + // + // Name change. + // + if (NameChangeFlag) { + // + // Close the handles first + // + if (PrivateFile->IsOpenedByRead) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + for (CharPointer = NewFileName; *CharPointer != 0 && *CharPointer != L'/'; CharPointer++) { + } + + if (*CharPointer != 0) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + if (PrivateFile->LHandle != INVALID_HANDLE_VALUE) { + if (PrivateFile->IsDirectoryPath) { + FindClose (PrivateFile->LHandle); + } else { + CloseHandle (PrivateFile->LHandle); + PrivateFile->LHandle = INVALID_HANDLE_VALUE; + } + } + + if (PrivateFile->IsDirectoryPath && PrivateFile->DirHandle != INVALID_HANDLE_VALUE) { + CloseHandle (PrivateFile->DirHandle); + PrivateFile->DirHandle = INVALID_HANDLE_VALUE; + } + + NtStatus = MoveFile (OldFileName, NewFileName); + + if (NtStatus) { + // + // modify file name + // + FreePool (PrivateFile->FileName); + + PrivateFile->FileName = AllocatePool (StrSize (NewFileName)); + if (PrivateFile->FileName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + StrCpyS (PrivateFile->FileName, StrSize (NewFileName) / sizeof (CHAR16), NewFileName); + + Size = StrSize (NewFileName); + Size += StrSize (L"\\*"); + TempFileName = AllocatePool (Size); + + StrCpyS (TempFileName, Size / sizeof (CHAR16), NewFileName); + + if (!PrivateFile->IsDirectoryPath) { + PrivateFile->LHandle = CreateFile ( + TempFileName, + PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + + FreePool (TempFileName); + + // + // Flush buffers just in case + // + if (FlushFileBuffers (PrivateFile->LHandle) == 0) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + } else { + PrivateFile->DirHandle = CreateFile ( + TempFileName, + PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL + ); + + StrCatS (TempFileName, Size / sizeof (CHAR16), L"\\*"); + PrivateFile->LHandle = FindFirstFile (TempFileName, &FindBuf); + + FreePool (TempFileName); + } + } else { + Status = EFI_ACCESS_DENIED; + Reopen:; + + NtStatus = SetFileAttributes (OldFileName, OldAttr); + + if (!NtStatus) { + goto Done; + } + + Size = StrSize (OldFileName); + Size += StrSize (L"\\*"); + TempFileName = AllocatePool (Size); + + StrCpyS (TempFileName, Size / sizeof (CHAR16), OldFileName); + + if (!PrivateFile->IsDirectoryPath) { + PrivateFile->LHandle = CreateFile ( + TempFileName, + PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, + NULL + ); + } else { + PrivateFile->DirHandle = CreateFile ( + TempFileName, + PrivateFile->IsOpenedByRead ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL + ); + + StrCatS (TempFileName, Size / sizeof (CHAR16), L"\\*"); + PrivateFile->LHandle = FindFirstFile (TempFileName, &FindBuf); + } + + FreePool (TempFileName); + + goto Done; + + } + } + + // + // Size change + // + if (SizeChangeFlag) { + if (PrivateFile->IsDirectoryPath) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + if (PrivateFile->IsOpenedByRead || OldFileInfo->Attribute & EFI_FILE_READ_ONLY) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + Status = This->GetPosition (This, &CurPos); + if (EFI_ERROR (Status)) { + goto Done; + } + + Status = This->SetPosition (This, NewFileInfo->FileSize); + if (EFI_ERROR (Status)) { + goto Done; + } + + if (SetEndOfFile (PrivateFile->LHandle) == 0) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + Status = This->SetPosition (This, CurPos); + if (EFI_ERROR (Status)) { + goto Done; + } + } + + // + // Time change + // + if (TimeChangeFlag) { + + NewCreationSystemTime.wYear = NewFileInfo->CreateTime.Year; + NewCreationSystemTime.wMonth = NewFileInfo->CreateTime.Month; + NewCreationSystemTime.wDay = NewFileInfo->CreateTime.Day; + NewCreationSystemTime.wHour = NewFileInfo->CreateTime.Hour; + NewCreationSystemTime.wMinute = NewFileInfo->CreateTime.Minute; + NewCreationSystemTime.wSecond = NewFileInfo->CreateTime.Second; + NewCreationSystemTime.wMilliseconds = 0; + + if (!SystemTimeToFileTime ( + &NewCreationSystemTime, + &NewCreationFileTime + )) { + goto Done; + } + + if (!LocalFileTimeToFileTime ( + &NewCreationFileTime, + &NewCreationFileTime + )) { + goto Done; + } + + NewLastAccessSystemTime.wYear = NewFileInfo->LastAccessTime.Year; + NewLastAccessSystemTime.wMonth = NewFileInfo->LastAccessTime.Month; + NewLastAccessSystemTime.wDay = NewFileInfo->LastAccessTime.Day; + NewLastAccessSystemTime.wHour = NewFileInfo->LastAccessTime.Hour; + NewLastAccessSystemTime.wMinute = NewFileInfo->LastAccessTime.Minute; + NewLastAccessSystemTime.wSecond = NewFileInfo->LastAccessTime.Second; + NewLastAccessSystemTime.wMilliseconds = 0; + + if (!SystemTimeToFileTime ( + &NewLastAccessSystemTime, + &NewLastAccessFileTime + )) { + goto Done; + } + + if (!LocalFileTimeToFileTime ( + &NewLastAccessFileTime, + &NewLastAccessFileTime + )) { + goto Done; + } + + NewLastWriteSystemTime.wYear = NewFileInfo->ModificationTime.Year; + NewLastWriteSystemTime.wMonth = NewFileInfo->ModificationTime.Month; + NewLastWriteSystemTime.wDay = NewFileInfo->ModificationTime.Day; + NewLastWriteSystemTime.wHour = NewFileInfo->ModificationTime.Hour; + NewLastWriteSystemTime.wMinute = NewFileInfo->ModificationTime.Minute; + NewLastWriteSystemTime.wSecond = NewFileInfo->ModificationTime.Second; + NewLastWriteSystemTime.wMilliseconds = 0; + + if (!SystemTimeToFileTime ( + &NewLastWriteSystemTime, + &NewLastWriteFileTime + )) { + goto Done; + } + + if (!LocalFileTimeToFileTime ( + &NewLastWriteFileTime, + &NewLastWriteFileTime + )) { + goto Done; + } + + if (!SetFileTime ( + PrivateFile->IsDirectoryPath ? PrivateFile->DirHandle : PrivateFile->LHandle, + &NewCreationFileTime, + &NewLastAccessFileTime, + &NewLastWriteFileTime + )) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + } + + // + // No matter about AttrChangeFlag, Attribute must be set. + // Because operation before may cause attribute change. + // + NewAttr = OldAttr; + + if (NewFileInfo->Attribute & EFI_FILE_ARCHIVE) { + NewAttr |= FILE_ATTRIBUTE_ARCHIVE; + } else { + NewAttr &= ~FILE_ATTRIBUTE_ARCHIVE; + } + + if (NewFileInfo->Attribute & EFI_FILE_HIDDEN) { + NewAttr |= FILE_ATTRIBUTE_HIDDEN; + } else { + NewAttr &= ~FILE_ATTRIBUTE_HIDDEN; + } + + if (NewFileInfo->Attribute & EFI_FILE_SYSTEM) { + NewAttr |= FILE_ATTRIBUTE_SYSTEM; + } else { + NewAttr &= ~FILE_ATTRIBUTE_SYSTEM; + } + + if (NewFileInfo->Attribute & EFI_FILE_READ_ONLY) { + NewAttr |= FILE_ATTRIBUTE_READONLY; + } else { + NewAttr &= ~FILE_ATTRIBUTE_READONLY; + } + + NtStatus = SetFileAttributes (NewFileName, NewAttr); + + if (!NtStatus) { + Status = EFI_DEVICE_ERROR; + goto Reopen; + } + +Done: + if (OldFileInfo != NULL) { + FreePool (OldFileInfo); + } + + if (OldFileName != NULL) { + FreePool (OldFileName); + } + + if (NewFileName != NULL) { + FreePool (NewFileName); + } + + return Status; +} + + +/** + Flush data back for the file handle. + + @param This Protocol instance pointer. + + @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_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 +WinNtFileFlush ( + IN EFI_FILE_PROTOCOL *This + ) +{ + BY_HANDLE_FILE_INFORMATION FileInfo; + WIN_NT_EFI_FILE_PRIVATE *PrivateFile; + EFI_STATUS Status; + + PrivateFile = WIN_NT_EFI_FILE_PRIVATE_DATA_FROM_THIS (This); + + if (PrivateFile->LHandle == INVALID_HANDLE_VALUE) { + Status = EFI_DEVICE_ERROR; + goto Done; + } + + if (PrivateFile->IsDirectoryPath) { + Status = EFI_SUCCESS; + goto Done; + } + + if (PrivateFile->IsOpenedByRead) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + GetFileInformationByHandle (PrivateFile->LHandle, &FileInfo); + + if (FileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + Status = FlushFileBuffers (PrivateFile->LHandle) ? EFI_SUCCESS : EFI_DEVICE_ERROR; + +Done: + return Status; + // + // bugbug: - Use Windows error reporting. + // + +} + + + +EFI_STATUS +WinNtFileSystmeThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + + Private = AllocateZeroPool (sizeof (*Private)); + if (Private == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Private->FilePath = AllocateCopyPool (StrSize (This->ConfigString), This->ConfigString); + if (Private->FilePath == NULL) { + FreePool (Private); + return EFI_OUT_OF_RESOURCES; + } + + Private->VolumeLabel = AllocateCopyPool (StrSize (L"EFI_EMULATED"), L"EFI_EMULATED"); + if (Private->VolumeLabel == NULL) { + FreePool (Private->FilePath); + FreePool (Private); + return EFI_OUT_OF_RESOURCES; + } + + Private->Signature = WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE_SIGNATURE; + Private->Thunk = This; + CopyMem (&Private->SimpleFileSystem, &gWinNtFileSystemProtocol, sizeof (Private->SimpleFileSystem)); + + This->Interface = &Private->SimpleFileSystem; + This->Private = Private; + return EFI_SUCCESS; +} + + +EFI_STATUS +WinNtFileSystmeThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private; + + Private = This->Private; + ASSERT (Private != NULL); + + if (Private->VolumeLabel != NULL) { + FreePool (Private->VolumeLabel); + } + if (Private->FilePath != NULL) { + FreePool (Private->FilePath); + } + FreePool (Private); + return EFI_SUCCESS; +} + + +EFI_FILE_PROTOCOL gWinNtFileProtocol = { + EFI_FILE_REVISION, + WinNtFileOpen, + WinNtFileClose, + WinNtFileDelete, + WinNtFileRead, + WinNtFileWrite, + WinNtFileGetPossition, + WinNtFileSetPossition, + WinNtFileGetInfo, + WinNtFileSetInfo, + WinNtFileFlush +}; + +EFI_SIMPLE_FILE_SYSTEM_PROTOCOL gWinNtFileSystemProtocol = { + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION, + WinNtOpenVolume +}; + + +EMU_IO_THUNK_PROTOCOL mWinNtFileSystemThunkIo = { + &gEfiSimpleFileSystemProtocolGuid, + NULL, + NULL, + 0, + WinNtFileSystmeThunkOpen, + WinNtFileSystmeThunkClose, + NULL +}; + + diff --git a/CdeEmuPkg/EmulatorPkg/Win/Host/WinGop.h b/CdeEmuPkg/EmulatorPkg/Win/Host/WinGop.h new file mode 100644 index 00000000000..665e9f248e3 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/Host/WinGop.h @@ -0,0 +1,204 @@ +/** @file + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +Module Name: + + WinGop.h + +Abstract: + + Private data for the Gop driver that is bound to the WinNt Thunk protocol + + +**/ + +#ifndef _WIN_GOP_H_ +#define _WIN_GOP_H_ + + +#include "WinHost.h" + +#include +#include +#include +#include +#include +#include +#include + +// +// WM_SYSKEYDOWN/WM_SYSKEYUP Notification +// lParam +// bit 24: Specifies whether the key is an extended key, +// such as the right-hand ALT and CTRL keys that appear on +// an enhanced 101- or 102-key keyboard. +// The value is 1 if it is an extended key; otherwise, it is 0. +// bit 29:Specifies the context code. +// The value is 1 if the ALT key is down while the key is pressed/released; +// it is 0 if the WM_SYSKEYDOWN message is posted to the active window +// because no window has the keyboard focus. +#define GOP_EXTENDED_KEY (0x1 << 24) +#define GOP_ALT_KEY_PRESSED (0x1 << 29) + +#define KEYBOARD_TIMER_INTERVAL 200000 // 0.02s + +#define MAX_Q 256 + +typedef struct { + UINTN Front; + UINTN Rear; + EFI_KEY_DATA Q[MAX_Q]; + CRITICAL_SECTION Cs; +} GOP_QUEUE_FIXED; + +#define WIN_NT_GOP_CLASS_NAME L"WinNtGopWindow" + + +typedef struct { + UINT64 Signature; + EMU_GRAPHICS_WINDOW_PROTOCOL GraphicsWindowIo; + + // + // GOP Private Data knowing when to start hardware + // + BOOLEAN HardwareNeedsStarting; + + CHAR16 *WindowName; + CHAR16 Buffer[160]; + + HANDLE ThreadInited; // Semaphore + HANDLE ThreadHandle; // Thread + DWORD ThreadId; + + HWND WindowHandle; + WNDCLASSEX WindowsClass; + + UINT32 Width; + UINT32 Height; + // + // This screen is used to redraw the screen when windows events happen. It's + // updated in the main thread and displayed in the windows thread. + // + BITMAPV4HEADER *VirtualScreenInfo; + + FRAME_BUFFER_CONFIGURE *FrameBufferConfigure; + + // + // Keyboard Queue used by Simple Text In. + // QueueForRead: WinProc thread adds, and main thread removes. + // + GOP_QUEUE_FIXED QueueForRead; + + EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeRegisterdKeyCallback; + EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakRegisterdKeyCallback; + VOID *RegisterdKeyCallbackContext; + + EFI_KEY_STATE KeyState; + BOOLEAN LeftShift; + BOOLEAN RightShift; + BOOLEAN LeftAlt; + BOOLEAN RightAlt; + BOOLEAN LeftCtrl; + BOOLEAN RightCtrl; + BOOLEAN LeftLogo; + BOOLEAN RightLogo; + BOOLEAN Menu; + BOOLEAN SysReq; + BOOLEAN NumLock; + BOOLEAN ScrollLock; + BOOLEAN CapsLock; + BOOLEAN IsPartialKeySupport; + INT32 PointerPreviousX; + INT32 PointerPreviousY; + BOOLEAN PointerStateChanged; + EFI_SIMPLE_POINTER_STATE PointerState; +} GRAPHICS_PRIVATE_DATA; +#define GRAPHICS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('g', 'f', 'x', 'd') +#define GRAPHICS_PRIVATE_DATA_FROM_THIS(a) \ + CR(a, GRAPHICS_PRIVATE_DATA, GraphicsWindowIo, GRAPHICS_PRIVATE_DATA_SIGNATURE) + + +// +// Gop Hardware abstraction internal worker functions +// + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Key TODO: add argument description + + @return TODO: add return values + +**/ +EFI_STATUS +GopPrivateAddKey ( + IN GRAPHICS_PRIVATE_DATA *Private, + IN EFI_INPUT_KEY Key + ); + +EFI_STATUS +EFIAPI +WinNtWndGetKey ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_KEY_DATA *KeyData + ); + +EFI_STATUS +EFIAPI +WinNtWndCheckKey ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo + ); + +EFI_STATUS +EFIAPI +WinNtWndKeySetState ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_KEY_TOGGLE_STATE *KeyToggleState + ); + +EFI_STATUS +EFIAPI +WinNtWndRegisterKeyNotify ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeCallBack, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakCallBack, + IN VOID *Context + ); + +EFI_STATUS +EFIAPI +WinNtWndCheckPointer ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo + ); + +EFI_STATUS +EFIAPI +WinNtWndGetPointerState ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_SIMPLE_POINTER_STATE *State + ); +EFI_STATUS +GopPrivateCreateQ ( + IN GRAPHICS_PRIVATE_DATA *Private, + IN GOP_QUEUE_FIXED *Queue + ); + + +/** + TODO: Add function description + + @param Private TODO: add argument description + + @retval EFI_SUCCESS TODO: Add description for return value + +**/ +EFI_STATUS +GopPrivateDestroyQ ( + IN GRAPHICS_PRIVATE_DATA *Private, + IN GOP_QUEUE_FIXED *Queue + ); +#endif + diff --git a/CdeEmuPkg/EmulatorPkg/Win/Host/WinGopInput.c b/CdeEmuPkg/EmulatorPkg/Win/Host/WinGopInput.c new file mode 100644 index 00000000000..5679c7b46d2 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/Host/WinGopInput.c @@ -0,0 +1,447 @@ +/** @file + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +Module Name: + + WinGopInput.c + +Abstract: + + This file produces the Simple Text In for an Gop window. + + This stuff is linked at the hip to the Window, since the window + processing is done in a thread kicked off in WinNtGopImplementation.c + + Since the window information is processed in an other thread we need + a keyboard Queue to pass data about. The Simple Text In code just + takes data off the Queue. The WinProc message loop takes keyboard input + and places it in the Queue. + + +**/ + + +#include "WinGop.h" + + +/** + TODO: Add function description + + @param Private TODO: add argument description + + @retval EFI_SUCCESS TODO: Add description for return value + +**/ +EFI_STATUS +GopPrivateCreateQ ( + IN GRAPHICS_PRIVATE_DATA *Private, + IN GOP_QUEUE_FIXED *Queue + ) +{ + InitializeCriticalSection (&Queue->Cs); + Queue->Front = 0; + Queue->Rear = 0; + return EFI_SUCCESS; +} + + +/** + TODO: Add function description + + @param Private TODO: add argument description + + @retval EFI_SUCCESS TODO: Add description for return value + +**/ +EFI_STATUS +GopPrivateDestroyQ ( + IN GRAPHICS_PRIVATE_DATA *Private, + IN GOP_QUEUE_FIXED *Queue + ) +{ + Queue->Front = 0; + Queue->Rear = 0; + DeleteCriticalSection (&Queue->Cs); + return EFI_SUCCESS; +} + + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Key TODO: add argument description + + @retval EFI_NOT_READY TODO: Add description for return value + @retval EFI_SUCCESS TODO: Add description for return value + +**/ +EFI_STATUS +GopPrivateAddQ ( + IN GRAPHICS_PRIVATE_DATA *Private, + IN GOP_QUEUE_FIXED *Queue, + IN EFI_KEY_DATA *KeyData + ) +{ + EnterCriticalSection (&Queue->Cs); + + if ((Queue->Rear + 1) % MAX_Q == Queue->Front) { + LeaveCriticalSection (&Queue->Cs); + return EFI_NOT_READY; + } + + CopyMem (&Queue->Q[Queue->Rear], KeyData, sizeof (EFI_KEY_DATA)); + Queue->Rear = (Queue->Rear + 1) % MAX_Q; + + LeaveCriticalSection (&Queue->Cs); + return EFI_SUCCESS; +} + + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Key TODO: add argument description + + @retval EFI_NOT_READY TODO: Add description for return value + @retval EFI_SUCCESS TODO: Add description for return value + +**/ +EFI_STATUS +GopPrivateDeleteQ ( + IN GRAPHICS_PRIVATE_DATA *Private, + IN GOP_QUEUE_FIXED *Queue, + OUT EFI_KEY_DATA *Key + ) +{ + EnterCriticalSection (&Queue->Cs); + + if (Queue->Front == Queue->Rear) { + LeaveCriticalSection (&Queue->Cs); + return EFI_NOT_READY; + } + + CopyMem (Key, &Queue->Q[Queue->Front], sizeof (EFI_KEY_DATA)); + Queue->Front = (Queue->Front + 1) % MAX_Q; + + if (Key->Key.ScanCode == SCAN_NULL && Key->Key.UnicodeChar == CHAR_NULL) { + if (!Private->IsPartialKeySupport) { + // + // If partial keystrok is not enabled, don't return the partial keystroke. + // + LeaveCriticalSection (&Queue->Cs); + ZeroMem (Key, sizeof (EFI_KEY_DATA)); + return EFI_NOT_READY; + } + } + LeaveCriticalSection (&Queue->Cs); + return EFI_SUCCESS; +} + + +/** + TODO: Add function description + + @param Private TODO: add argument description + + @retval EFI_NOT_READY TODO: Add description for return value + @retval EFI_SUCCESS TODO: Add description for return value + +**/ +EFI_STATUS +GopPrivateCheckQ ( + IN GOP_QUEUE_FIXED *Queue + ) +{ + if (Queue->Front == Queue->Rear) { + return EFI_NOT_READY; + } + + return EFI_SUCCESS; +} + +/** + Initialize the key state. + + @param Private The GOP_PRIVATE_DATA instance. + @param KeyState A pointer to receive the key state information. +**/ +VOID +InitializeKeyState ( + IN GRAPHICS_PRIVATE_DATA *Private, + IN EFI_KEY_STATE *KeyState + ) +{ + KeyState->KeyShiftState = EFI_SHIFT_STATE_VALID; + KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID; + + // + // Record Key shift state and toggle state + // + if (Private->LeftCtrl) { + KeyState->KeyShiftState |= EFI_LEFT_CONTROL_PRESSED; + } + if (Private->RightCtrl) { + KeyState->KeyShiftState |= EFI_RIGHT_CONTROL_PRESSED; + } + if (Private->LeftAlt) { + KeyState->KeyShiftState |= EFI_LEFT_ALT_PRESSED; + } + if (Private->RightAlt) { + KeyState->KeyShiftState |= EFI_RIGHT_ALT_PRESSED; + } + if (Private->LeftShift) { + KeyState->KeyShiftState |= EFI_LEFT_SHIFT_PRESSED; + } + if (Private->RightShift) { + KeyState->KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED; + } + if (Private->LeftLogo) { + KeyState->KeyShiftState |= EFI_LEFT_LOGO_PRESSED; + } + if (Private->RightLogo) { + KeyState->KeyShiftState |= EFI_RIGHT_LOGO_PRESSED; + } + if (Private->Menu) { + KeyState->KeyShiftState |= EFI_MENU_KEY_PRESSED; + } + if (Private->SysReq) { + KeyState->KeyShiftState |= EFI_SYS_REQ_PRESSED; + } + if (Private->CapsLock) { + KeyState->KeyToggleState |= EFI_CAPS_LOCK_ACTIVE; + } + if (Private->NumLock) { + KeyState->KeyToggleState |= EFI_NUM_LOCK_ACTIVE; + } + if (Private->ScrollLock) { + KeyState->KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE; + } + if (Private->IsPartialKeySupport) { + KeyState->KeyToggleState |= EFI_KEY_STATE_EXPOSED; + } +} + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param Key TODO: add argument description + + @retval EFI_NOT_READY TODO: Add description for return value + @retval EFI_SUCCESS TODO: Add description for return value + +**/ +EFI_STATUS +GopPrivateAddKey ( + IN GRAPHICS_PRIVATE_DATA *Private, + IN EFI_INPUT_KEY Key + ) +{ + EFI_KEY_DATA KeyData; + + KeyData.Key = Key; + InitializeKeyState (Private, &KeyData.KeyState); + + // + // Convert Ctrl+[1-26] to Ctrl+[A-Z] + // + if ((Private->LeftCtrl || Private->RightCtrl) && + (KeyData.Key.UnicodeChar >= 1) && (KeyData.Key.UnicodeChar <= 26) + ) { + if ((Private->LeftShift || Private->RightShift) == Private->CapsLock) { + KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'a' - 1); + } else { + KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar + L'A' - 1); + } + } + + // + // Unmask the Shift bit for printable char + // + if (((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) || + ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z')) + ) { + KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED); + } + + GopPrivateAddQ (Private, &Private->QueueForRead, &KeyData); + if (Private->MakeRegisterdKeyCallback != NULL) { + Private->MakeRegisterdKeyCallback (Private->RegisterdKeyCallbackContext, &KeyData); + } + + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +WinNtWndCheckKey ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo + ) +{ + GRAPHICS_PRIVATE_DATA *Private; + + Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); + + return GopPrivateCheckQ (&Private->QueueForRead); + +} +EFI_STATUS +EFIAPI +WinNtWndGetKey ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_KEY_DATA *KeyData + ) +/*++ + + Routine Description: + Reads the next keystroke from the input device. The WaitForKey Event can + be used to test for existence of a keystroke via WaitForEvent () call. + + Arguments: + Private - The private structure of WinNt Gop device. + 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 available. + EFI_DEVICE_ERROR - The keystroke information was not returned due to + hardware errors. + EFI_INVALID_PARAMETER - KeyData is NULL. + +--*/ +{ + EFI_STATUS Status; + GRAPHICS_PRIVATE_DATA *Private; + + Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); + + ZeroMem (&KeyData->Key, sizeof (KeyData->Key)); + InitializeKeyState (Private, &KeyData->KeyState); + + Status = GopPrivateCheckQ (&Private->QueueForRead); + if (!EFI_ERROR (Status)) { + // + // If a Key press exists try and read it. + // + Status = GopPrivateDeleteQ (Private, &Private->QueueForRead, KeyData); + if (!EFI_ERROR (Status)) { + // + // If partial keystroke is not enabled, check whether it is value key. If not return + // EFI_NOT_READY. + // + if (!Private->IsPartialKeySupport) { + if (KeyData->Key.ScanCode == SCAN_NULL && KeyData->Key.UnicodeChar == CHAR_NULL) { + Status = EFI_NOT_READY; + } + } + } + } + + return Status; + +} + +EFI_STATUS +EFIAPI +WinNtWndKeySetState ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_KEY_TOGGLE_STATE *KeyToggleState + ) +{ + GRAPHICS_PRIVATE_DATA *Private; + + Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); + Private->ScrollLock = FALSE; + Private->NumLock = FALSE; + Private->CapsLock = FALSE; + Private->IsPartialKeySupport = FALSE; + + if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) { + Private->ScrollLock = TRUE; + } + if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) { + Private->NumLock = TRUE; + } + if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) { + Private->CapsLock = TRUE; + } + if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) { + Private->IsPartialKeySupport = TRUE; + } + Private->KeyState.KeyToggleState = *KeyToggleState; + return EFI_SUCCESS; +} + + +EFI_STATUS +EFIAPI +WinNtWndRegisterKeyNotify ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK MakeCallBack, + IN EMU_GRAPHICS_WINDOW_REGISTER_KEY_NOTIFY_CALLBACK BreakCallBack, + IN VOID *Context + ) +{ + GRAPHICS_PRIVATE_DATA *Private; + + Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); + + Private->MakeRegisterdKeyCallback = MakeCallBack; + Private->BreakRegisterdKeyCallback = BreakCallBack; + Private->RegisterdKeyCallbackContext = Context; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +WinNtWndCheckPointer ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo + ) +{ + GRAPHICS_PRIVATE_DATA *Private; + + Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); + + if (!Private->PointerStateChanged) { + return EFI_NOT_READY; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +WinNtWndGetPointerState ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_SIMPLE_POINTER_STATE *State + ) +{ + GRAPHICS_PRIVATE_DATA *Private; + + Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); + + if (!Private->PointerStateChanged) { + return EFI_NOT_READY; + } + + State->RelativeMovementX = Private->PointerState.RelativeMovementX; + State->RelativeMovementY = Private->PointerState.RelativeMovementY; + State->RelativeMovementZ = Private->PointerState.RelativeMovementZ; + State->LeftButton = Private->PointerState.LeftButton; + State->RightButton = Private->PointerState.RightButton; + + Private->PointerState.RelativeMovementX = 0; + Private->PointerState.RelativeMovementY = 0; + Private->PointerState.RelativeMovementZ = 0; + + Private->PointerStateChanged = FALSE; + + return EFI_SUCCESS; +} diff --git a/CdeEmuPkg/EmulatorPkg/Win/Host/WinGopScreen.c b/CdeEmuPkg/EmulatorPkg/Win/Host/WinGopScreen.c new file mode 100644 index 00000000000..6db6595886e --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/Host/WinGopScreen.c @@ -0,0 +1,827 @@ +/** @file + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +Module Name: + + WinGopScreen.c + +Abstract: + + This file produces the graphics abstration of GOP. It is called by + WinNtGopDriver.c file which deals with the UEFI 2.0 driver model. + This file just does graphics. + + +**/ + +#include "WinGop.h" + +DWORD mTlsIndex = TLS_OUT_OF_INDEXES; +DWORD mTlsIndexUseCount = 0; // lets us know when we can free mTlsIndex. + +BOOLEAN +WinNtGopConvertParamToEfiKeyShiftState ( + IN GRAPHICS_PRIVATE_DATA *Private, + IN WPARAM *wParam, + IN LPARAM *lParam, + IN BOOLEAN Flag + ) +{ + switch (*wParam) { + // + // BUGBUG: Only GetAsyncKeyState() and GetKeyState() can distinguish + // left and right Ctrl, and Shift key. + // Neither of the two is defined in EFI_WIN_NT_THUNK_PROTOCOL. + // Therefor, we can not set the correct Shift state here. + // + case VK_SHIFT: + if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) { + Private->RightShift = Flag; + } else { + Private->LeftShift = Flag; + } + return TRUE; + + case VK_LSHIFT: + Private->LeftShift = Flag; + return TRUE; + + case VK_RSHIFT: + Private->RightShift = Flag; + return TRUE; + + case VK_CONTROL: + if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) { + Private->RightCtrl= Flag; + } else { + Private->LeftCtrl = Flag; + } + return TRUE; + + case VK_LCONTROL: + Private->LeftCtrl = Flag; + return TRUE; + + case VK_RCONTROL: + Private->RightCtrl = Flag; + return TRUE; + + case VK_LWIN: + Private->LeftLogo = Flag; + return TRUE; + + case VK_RWIN: + Private->RightLogo = Flag; + return TRUE; + + case VK_APPS: + Private->Menu = Flag; + return TRUE; + // + // BUGBUG: PrintScreen/SysRq can not trigger WM_KEYDOWN message, + // so SySReq shift state is not supported here. + // + case VK_PRINT: + Private->SysReq = Flag; + return TRUE; + // + // For Alt Keystroke. + // + case VK_MENU: + if ((*lParam & GOP_EXTENDED_KEY) == GOP_EXTENDED_KEY) { + Private->RightAlt = Flag; + } else { + Private->LeftAlt = Flag; + } + return TRUE; + + default: + return FALSE; + } +} + +BOOLEAN +WinNtGopConvertParamToEfiKey ( + IN GRAPHICS_PRIVATE_DATA *Private, + IN WPARAM *wParam, + IN LPARAM *lParam, + IN EFI_INPUT_KEY *Key + ) +{ + BOOLEAN Flag; + Flag = FALSE; + switch (*wParam) { + case VK_HOME: Key->ScanCode = SCAN_HOME; Flag = TRUE; break; + case VK_END: Key->ScanCode = SCAN_END; Flag = TRUE; break; + case VK_LEFT: Key->ScanCode = SCAN_LEFT; Flag = TRUE; break; + case VK_RIGHT: Key->ScanCode = SCAN_RIGHT; Flag = TRUE; break; + case VK_UP: Key->ScanCode = SCAN_UP; Flag = TRUE; break; + case VK_DOWN: Key->ScanCode = SCAN_DOWN; Flag = TRUE; break; + case VK_DELETE: Key->ScanCode = SCAN_DELETE; Flag = TRUE; break; + case VK_INSERT: Key->ScanCode = SCAN_INSERT; Flag = TRUE; break; + case VK_PRIOR: Key->ScanCode = SCAN_PAGE_UP; Flag = TRUE; break; + case VK_NEXT: Key->ScanCode = SCAN_PAGE_DOWN; Flag = TRUE; break; + case VK_ESCAPE: Key->ScanCode = SCAN_ESC; Flag = TRUE; break; + + case VK_F1: Key->ScanCode = SCAN_F1; Flag = TRUE; break; + case VK_F2: Key->ScanCode = SCAN_F2; Flag = TRUE; break; + case VK_F3: Key->ScanCode = SCAN_F3; Flag = TRUE; break; + case VK_F4: Key->ScanCode = SCAN_F4; Flag = TRUE; break; + case VK_F5: Key->ScanCode = SCAN_F5; Flag = TRUE; break; + case VK_F6: Key->ScanCode = SCAN_F6; Flag = TRUE; break; + case VK_F7: Key->ScanCode = SCAN_F7; Flag = TRUE; break; + case VK_F8: Key->ScanCode = SCAN_F8; Flag = TRUE; break; + case VK_F9: Key->ScanCode = SCAN_F9; Flag = TRUE; break; + case VK_F11: Key->ScanCode = SCAN_F11; Flag = TRUE; break; + case VK_F12: Key->ScanCode = SCAN_F12; Flag = TRUE; break; + + case VK_F13: Key->ScanCode = SCAN_F13; Flag = TRUE; break; + case VK_F14: Key->ScanCode = SCAN_F14; Flag = TRUE; break; + case VK_F15: Key->ScanCode = SCAN_F15; Flag = TRUE; break; + case VK_F16: Key->ScanCode = SCAN_F16; Flag = TRUE; break; + case VK_F17: Key->ScanCode = SCAN_F17; Flag = TRUE; break; + case VK_F18: Key->ScanCode = SCAN_F18; Flag = TRUE; break; + case VK_F19: Key->ScanCode = SCAN_F19; Flag = TRUE; break; + case VK_F20: Key->ScanCode = SCAN_F20; Flag = TRUE; break; + case VK_F21: Key->ScanCode = SCAN_F21; Flag = TRUE; break; + case VK_F22: Key->ScanCode = SCAN_F22; Flag = TRUE; break; + case VK_F23: Key->ScanCode = SCAN_F23; Flag = TRUE; break; + case VK_F24: Key->ScanCode = SCAN_F24; Flag = TRUE; break; + case VK_PAUSE: Key->ScanCode = SCAN_PAUSE; Flag = TRUE; break; + + // + // Set toggle state + // + case VK_NUMLOCK: + Private->NumLock = (BOOLEAN)(!Private->NumLock); + Flag = TRUE; + break; + case VK_SCROLL: + Private->ScrollLock = (BOOLEAN)(!Private->ScrollLock); + Flag = TRUE; + break; + case VK_CAPITAL: + Private->CapsLock = (BOOLEAN)(!Private->CapsLock); + Flag = TRUE; + break; + } + + return (WinNtGopConvertParamToEfiKeyShiftState (Private, wParam, lParam, TRUE)) == TRUE ? TRUE : Flag; +} + + +// +// GOP Protocol Member Functions +// + +/** + Change the resolution and resize of the window +**/ +EFI_STATUS +EFIAPI +WinNtWndSize ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN UINT32 Width, + IN UINT32 Height +) +{ + RETURN_STATUS RStatus; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION Info; + GRAPHICS_PRIVATE_DATA *Private; + RECT Rect; + BITMAPV4HEADER *VirtualScreenInfo; + FRAME_BUFFER_CONFIGURE *FrameBufferConfigure; + UINTN FrameBufferConfigureSize; + + Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); + + // + // Allocate DIB frame buffer directly from NT for performance enhancement + // This buffer is the virtual screen/frame buffer. + // + VirtualScreenInfo = HeapAlloc ( + GetProcessHeap (), + HEAP_ZERO_MEMORY, + Width * Height * sizeof (RGBQUAD) + sizeof (BITMAPV4HEADER) + ); + if (VirtualScreenInfo == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Update the virtual screen info data structure + // Use negative Height to make sure screen/buffer are using the same coordinate. + // + VirtualScreenInfo->bV4Size = sizeof (BITMAPV4HEADER); + VirtualScreenInfo->bV4Width = Width; + VirtualScreenInfo->bV4Height = -(LONG)Height; + VirtualScreenInfo->bV4Planes = 1; + VirtualScreenInfo->bV4BitCount = 32; + // + // uncompressed + // + VirtualScreenInfo->bV4V4Compression = BI_RGB; + + Info.HorizontalResolution = Width; + Info.VerticalResolution = Height; + Info.PixelFormat = PixelBlueGreenRedReserved8BitPerColor; + Info.PixelsPerScanLine = Width; + FrameBufferConfigureSize = 0; + RStatus = FrameBufferBltConfigure (VirtualScreenInfo + 1, &Info, NULL, &FrameBufferConfigureSize); + ASSERT (RStatus == EFI_BUFFER_TOO_SMALL); + FrameBufferConfigure = AllocatePool (FrameBufferConfigureSize); + if (FrameBufferConfigure == NULL) { + HeapFree (GetProcessHeap (), 0, VirtualScreenInfo); + return EFI_OUT_OF_RESOURCES; + } + RStatus = FrameBufferBltConfigure (VirtualScreenInfo + 1, &Info, FrameBufferConfigure, &FrameBufferConfigureSize); + ASSERT_RETURN_ERROR (RStatus); + + + if (Private->FrameBufferConfigure != NULL) { + FreePool (Private->FrameBufferConfigure); + } + Private->FrameBufferConfigure = FrameBufferConfigure; + + // + // Free the old buffer. We do not save the content of the old buffer since the + // screen is to be cleared anyway. Clearing the screen is required by the EFI spec. + // See UEFI spec -EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode() + // + if (Private->VirtualScreenInfo != NULL) { + HeapFree (GetProcessHeap (), 0, Private->VirtualScreenInfo); + } + Private->VirtualScreenInfo = VirtualScreenInfo; + + Private->Width = Width; + Private->Height = Height; + + // + // Use the AdjuctWindowRect fuction to calculate the real width and height + // of the new window including the border and caption + // + Rect.left = 0; + Rect.top = 0; + Rect.right = Width; + Rect.bottom = Height; + + AdjustWindowRect (&Rect, WS_OVERLAPPEDWINDOW, 0); + + Width = Rect.right - Rect.left; + Height = Rect.bottom - Rect.top; + + // + // Retrieve the original window position information + // + GetWindowRect (Private->WindowHandle, &Rect); + + // + // Adjust the window size + // + MoveWindow (Private->WindowHandle, Rect.left, Rect.top, (INT32)Width, (INT32)Height, TRUE); + + return EFI_SUCCESS; +} + +/** + Blt pixels from the rectangle (Width X Height) formed by the BltBuffer + onto the graphics screen starting a location (X, Y). (0, 0) is defined as + the upper left hand side of the screen. (X, Y) can be outside of the + current screen geometry and the BltBuffer will be cliped when it is + displayed. X and Y can be negative or positive. If Width or Height is + bigger than the current video screen the image will be clipped. + + @param This Protocol instance pointer. + @param X X location on graphics screen. + @param Y Y location on the graphics screen. + @param Width Width of BltBuffer. + @param Height Height of BltBuffer + @param BltOperation Operation to perform on BltBuffer and video memory + @param BltBuffer Buffer containing data to blt into video buffer. + This buffer has a size of + Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + @param SourceX If the BltOperation is a EfiCopyBlt this is the + source of the copy. For other BLT operations this + argument is not used. + @param SourceX If the BltOperation is a EfiCopyBlt this is the + source of the copy. For other BLT operations this + argument is not used. + + @retval EFI_SUCCESS The palette is updated with PaletteArray. + @retval EFI_INVALID_PARAMETER BltOperation is not valid. + @retval EFI_DEVICE_ERROR A hardware error occurred writing to the video + buffer. + +**/ +// TODO: SourceY - add argument and description to function comment +// TODO: DestinationX - add argument and description to function comment +// TODO: DestinationY - add argument and description to function comment +// TODO: Delta - add argument and description to function comment +EFI_STATUS +WinNtWndBlt ( + IN EMU_GRAPHICS_WINDOW_PROTOCOL *GraphicsIo, + IN EFI_UGA_PIXEL *BltBuffer OPTIONAL, + IN EFI_UGA_BLT_OPERATION BltOperation, + IN EMU_GRAPHICS_WINDOWS__BLT_ARGS *Args +) +{ + RETURN_STATUS RStatus; + GRAPHICS_PRIVATE_DATA *Private; + RECT Rect; + + Private = GRAPHICS_PRIVATE_DATA_FROM_THIS (GraphicsIo); + RStatus = FrameBufferBlt ( + Private->FrameBufferConfigure, + BltBuffer, + BltOperation, + Args->SourceX, Args->SourceY, + Args->DestinationX, Args->DestinationY, + Args->Width, Args->Height, + Args->Delta + ); + if (RETURN_ERROR (RStatus)) { + return (EFI_STATUS)RStatus; + } + + if (BltOperation != EfiBltVideoToBltBuffer) { + // + // Mark the area we just blted as Invalid so WM_PAINT will update. + // + Rect.left = (LONG)Args->DestinationX; + Rect.top = (LONG)Args->DestinationY; + Rect.right = (LONG)(Args->DestinationX + Args->Width); + Rect.bottom = (LONG)(Args->DestinationY + Args->Height); + InvalidateRect (Private->WindowHandle, &Rect, FALSE); + + // + // Send the WM_PAINT message to the thread that is drawing the window. We + // are in the main thread and the window drawing is in a child thread. + // There is a child thread per window. We have no CriticalSection or Mutex + // since we write the data and the other thread displays the data. While + // we may miss some data for a short period of time this is no different than + // a write combining on writes to a frame buffer. + // + + UpdateWindow (Private->WindowHandle); + } + + return EFI_SUCCESS; +} + + + +/** + Win32 Windows event handler. + + See Win32 Book + + @return See Win32 Book + +**/ +// TODO: hwnd - add argument and description to function comment +// TODO: iMsg - add argument and description to function comment +// TODO: wParam - add argument and description to function comment +// TODO: lParam - add argument and description to function comment +LRESULT +CALLBACK +WinNtGopThreadWindowProc ( + IN HWND hwnd, + IN UINT iMsg, + IN WPARAM wParam, + IN LPARAM lParam + ) +{ + GRAPHICS_PRIVATE_DATA *Private; + HDC Handle; + PAINTSTRUCT PaintStruct; + LPARAM Index; + EFI_INPUT_KEY Key; + BOOLEAN AltIsPress; + INT32 PosX; + INT32 PosY; + + // + // Use mTlsIndex global to get a Thread Local Storage version of Private. + // This works since each Gop protocol has a unique Private data instance and + // a unique thread. + // + AltIsPress = FALSE; + Private = TlsGetValue (mTlsIndex); + ASSERT (NULL != Private); + + switch (iMsg) { + case WM_PAINT: + Handle = BeginPaint (hwnd, &PaintStruct); + + SetDIBitsToDevice ( + Handle, // Destination Device Context + 0, // Destination X - 0 + 0, // Destination Y - 0 + Private->Width, // Width + Private->Height, // Height + 0, // Source X + 0, // Source Y + 0, // DIB Start Scan Line + Private->Height, // Number of scan lines + Private->VirtualScreenInfo + 1, // Address of array of DIB bits + (BITMAPINFO *) Private->VirtualScreenInfo, // Address of structure with bitmap info + DIB_RGB_COLORS // RGB or palette indexes + ); + + EndPaint (hwnd, &PaintStruct); + return 0; + + // + // F10 and the ALT key do not create a WM_KEYDOWN message, thus this special case + // WM_SYSKEYDOWN is posted when F10 is pressed or + // holds down ALT key and then presses another key. + // + case WM_SYSKEYDOWN: + + Key.ScanCode = 0; + Key.UnicodeChar = CHAR_NULL; + switch (wParam) { + case VK_F10: + Key.ScanCode = SCAN_F10; + Key.UnicodeChar = CHAR_NULL; + GopPrivateAddKey (Private, Key); + return 0; + } + + // + // If ALT or ALT + modifier key is pressed. + // + if (WinNtGopConvertParamToEfiKey (Private, &wParam, &lParam, &Key)) { + if (Key.ScanCode != 0){ + // + // If ALT is pressed with other ScanCode. + // Always revers the left Alt for simple. + // + Private->LeftAlt = TRUE; + } + GopPrivateAddKey (Private, Key); + // + // When Alt is released there is no windoes message, so + // clean it after using it. + // + Private->RightAlt = FALSE; + Private->LeftAlt = FALSE; + return 0; + } + AltIsPress = TRUE; + + case WM_CHAR: + // + // The ESC key also generate WM_CHAR. + // + if (wParam == 0x1B) { + return 0; + } + + if (AltIsPress == TRUE) { + // + // If AltIsPress is true that means the Alt key is pressed. + // + Private->LeftAlt = TRUE; + } + for (Index = 0; Index < (lParam & 0xffff); Index++) { + if (wParam != 0) { + Key.UnicodeChar = (CHAR16) wParam; + Key.ScanCode = SCAN_NULL; + GopPrivateAddKey (Private, Key); + } + } + if (AltIsPress == TRUE) { + // + // When Alt is released there is no windoes message, so + // clean it after using it. + // + Private->LeftAlt = FALSE; + Private->RightAlt = FALSE; + } + return 0; + + case WM_SYSKEYUP: + // + // ALT is pressed with another key released + // + WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, &lParam, FALSE); + return 0; + + case WM_KEYDOWN: + Key.ScanCode = SCAN_NULL; + Key.UnicodeChar = CHAR_NULL; + // + // A value key press will cause a WM_KEYDOWN first, then cause a WM_CHAR + // So if there is no modifier key updated, skip the WM_KEYDOWN even. + // + if (WinNtGopConvertParamToEfiKey (Private, &wParam, &lParam, &Key)) { + // + // Support the partial keystroke, add all keydown event into the queue. + // + GopPrivateAddKey (Private, Key); + } + return 0; + + case WM_KEYUP: + WinNtGopConvertParamToEfiKeyShiftState (Private, &wParam, &lParam, FALSE); + return 0; + + case WM_MOUSEMOVE: + PosX = GET_X_LPARAM (lParam); + PosY = GET_Y_LPARAM (lParam); + + if (Private->PointerPreviousX != PosX) { + Private->PointerState.RelativeMovementX += (PosX - Private->PointerPreviousX); + Private->PointerPreviousX = PosX; + Private->PointerStateChanged = TRUE; + } + + if (Private->PointerPreviousY != PosY) { + Private->PointerState.RelativeMovementY += (PosY - Private->PointerPreviousY); + Private->PointerPreviousY = PosY; + Private->PointerStateChanged = TRUE; + } + + Private->PointerState.RelativeMovementZ = 0; + return 0; + + case WM_LBUTTONDOWN: + Private->PointerState.LeftButton = TRUE; + Private->PointerStateChanged = TRUE; + return 0; + + case WM_LBUTTONUP: + Private->PointerState.LeftButton = FALSE; + Private->PointerStateChanged = TRUE; + return 0; + + case WM_RBUTTONDOWN: + Private->PointerState.RightButton = TRUE; + Private->PointerStateChanged = TRUE; + return 0; + + case WM_RBUTTONUP: + Private->PointerState.RightButton = FALSE; + Private->PointerStateChanged = TRUE; + return 0; + + case WM_CLOSE: + // + // This close message is issued by user, core is not aware of this, + // so don't release the window display resource, just hide the window. + // + ShowWindow (Private->WindowHandle, SW_HIDE); + return 0; + + case WM_DESTROY: + DestroyWindow (hwnd); + PostQuitMessage (0); + + HeapFree (GetProcessHeap (), 0, Private->VirtualScreenInfo); + + ExitThread (0); + + default: + break; + }; + + return DefWindowProc (hwnd, iMsg, wParam, lParam); +} + + +/** + This thread simulates the end of WinMain () application. Each Window needs + to process its events. The messages are dispatched to + WinNtGopThreadWindowProc (). + Be very careful since WinNtGopThreadWinMain () and WinNtGopThreadWindowProc () + are running in a separate thread. We have to do this to process the events. + + @param lpParameter Handle of window to manage. + + @return if a WM_QUIT message is returned exit. + +**/ +DWORD +WINAPI +WinNtGopThreadWinMain ( + LPVOID lpParameter + ) +{ + MSG Message; + GRAPHICS_PRIVATE_DATA *Private; + RECT Rect; + + Private = (GRAPHICS_PRIVATE_DATA *) lpParameter; + ASSERT (NULL != Private); + + // + // Since each thread has unique private data, save the private data in Thread + // Local Storage slot. Then the shared global mTlsIndex can be used to get + // thread specific context. + // + TlsSetValue (mTlsIndex, Private); + + Private->ThreadId = GetCurrentThreadId (); + + Private->WindowsClass.cbSize = sizeof (WNDCLASSEX); + Private->WindowsClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + Private->WindowsClass.lpfnWndProc = WinNtGopThreadWindowProc; + Private->WindowsClass.cbClsExtra = 0; + Private->WindowsClass.cbWndExtra = 0; + Private->WindowsClass.hInstance = NULL; + Private->WindowsClass.hIcon = LoadIcon (NULL, IDI_APPLICATION); + Private->WindowsClass.hCursor = LoadCursor (NULL, IDC_ARROW); + Private->WindowsClass.hbrBackground = (HBRUSH)(UINTN)COLOR_WINDOW; + Private->WindowsClass.lpszMenuName = NULL; + Private->WindowsClass.lpszClassName = WIN_NT_GOP_CLASS_NAME; + Private->WindowsClass.hIconSm = LoadIcon (NULL, IDI_APPLICATION); + + // + // Use 100 x 100 as initial Window size. + // + Private->Width = 100; + Private->Height = 100; + + + // + // This call will fail after the first time, but thats O.K. since we only need + // WIN_NT_GOP_CLASS_NAME to exist to create the window. + // + RegisterClassEx (&Private->WindowsClass); + + // + // Setting Rect values to allow for the AdjustWindowRect to provide + // us the correct sizes for the client area when doing the CreateWindowEx + // + Rect.top = 0; + Rect.bottom = Private->Height; + Rect.left = 0; + Rect.right = Private->Width; + + AdjustWindowRect (&Rect, WS_OVERLAPPEDWINDOW, 0); + + Private->WindowHandle = CreateWindowEx ( + 0, + WIN_NT_GOP_CLASS_NAME, + Private->WindowName, + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + Rect.right - Rect.left, + Rect.bottom - Rect.top, + NULL, + NULL, + NULL, + (VOID **)&Private + ); + + // + // The reset of this thread is the standard windows program. We need a separate + // thread since we must process the message loop to make windows act like + // windows. + // + + ShowWindow (Private->WindowHandle, SW_SHOW); + UpdateWindow (Private->WindowHandle); + + // + // Let the main thread get some work done + // + ReleaseSemaphore (Private->ThreadInited, 1, NULL); + + // + // This is the message loop that all Windows programs need. + // + while (GetMessage (&Message, Private->WindowHandle, 0, 0)) { + TranslateMessage (&Message); + DispatchMessage (&Message); + } + + return (DWORD)Message.wParam; +} + + +/** + TODO: Add function description + + @param Private TODO: add argument description + @param HorizontalResolution TODO: add argument description + @param VerticalResolution TODO: add argument description + @param ColorDepth TODO: add argument description + @param RefreshRate TODO: add argument description + + @return TODO: add return values + +**/ +EFI_STATUS +EFIAPI +WinNtGraphicsWindowOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + DWORD NewThreadId; + GRAPHICS_PRIVATE_DATA *Private; + + Private = AllocateZeroPool (sizeof (*Private)); + + GopPrivateCreateQ (Private, &Private->QueueForRead); + + Private->GraphicsWindowIo.Size = WinNtWndSize; + Private->GraphicsWindowIo.CheckKey = WinNtWndCheckKey; + Private->GraphicsWindowIo.GetKey = WinNtWndGetKey; + Private->GraphicsWindowIo.KeySetState = WinNtWndKeySetState; + Private->GraphicsWindowIo.RegisterKeyNotify = WinNtWndRegisterKeyNotify; + Private->GraphicsWindowIo.Blt = WinNtWndBlt; + Private->GraphicsWindowIo.CheckPointer = WinNtWndCheckPointer; + Private->GraphicsWindowIo.GetPointerState = WinNtWndGetPointerState; + + Private->WindowName = This->ConfigString; + // + // Initialize a Thread Local Storge variable slot. We use TLS to get the + // correct Private data instance into the windows thread. + // + if (mTlsIndex == TLS_OUT_OF_INDEXES) { + ASSERT (0 == mTlsIndexUseCount); + mTlsIndex = TlsAlloc (); + } + + // + // always increase the use count! + // + mTlsIndexUseCount++; + + Private->ThreadInited = CreateSemaphore (NULL, 0, 1, NULL); + Private->ThreadHandle = CreateThread ( + NULL, + 0, + WinNtGopThreadWinMain, + (VOID *) Private, + 0, + &NewThreadId + ); + + // + // The other thread has entered the windows message loop so we can + // continue our initialization. + // + WaitForSingleObject (Private->ThreadInited, INFINITE); + CloseHandle (Private->ThreadInited); + + This->Private = Private; + This->Interface = &Private->GraphicsWindowIo; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +WinNtGraphicsWindowClose ( + IN EMU_IO_THUNK_PROTOCOL *This +) +{ + GRAPHICS_PRIVATE_DATA *Private; + + Private = (GRAPHICS_PRIVATE_DATA *)This->Private; + + // + // BugBug: Shutdown GOP Hardware and any child devices. + // + SendMessage (Private->WindowHandle, WM_DESTROY, 0, 0); + CloseHandle (Private->ThreadHandle); + + mTlsIndexUseCount--; + + // + // The callback function for another window could still be called, + // so we need to make sure there are no more users of mTlsIndex. + // + if (0 == mTlsIndexUseCount) { + ASSERT (TLS_OUT_OF_INDEXES != mTlsIndex); + + TlsFree (mTlsIndex); + mTlsIndex = TLS_OUT_OF_INDEXES; + + UnregisterClass ( + Private->WindowsClass.lpszClassName, + Private->WindowsClass.hInstance + ); + } + + + GopPrivateDestroyQ (Private, &Private->QueueForRead); + return EFI_SUCCESS; +} + + +EMU_IO_THUNK_PROTOCOL mWinNtWndThunkIo = { + &gEmuGraphicsWindowProtocolGuid, + NULL, + NULL, + 0, + WinNtGraphicsWindowOpen, + WinNtGraphicsWindowClose, + NULL +}; diff --git a/CdeEmuPkg/EmulatorPkg/Win/Host/WinHost.c b/CdeEmuPkg/EmulatorPkg/Win/Host/WinHost.c new file mode 100644 index 00000000000..5c045618fee --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/Host/WinHost.c @@ -0,0 +1,1097 @@ +/**@file + WinNt emulator of pre-SEC phase. It's really a Win32 application, but this is + Ok since all the other modules for NT32 are NOT Win32 applications. + + This program gets NT32 PCD setting and figures out what the memory layout + will be, how may FD's will be loaded and also what the boot mode is. + + This code produces 128 K of temporary memory for the SEC stack by directly + allocate memory space with ReadWrite and Execute attribute. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+(C) Copyright 2016-2020 Hewlett Packard Enterprise Development LP
+SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "WinHost.h" + +#ifndef SE_TIME_ZONE_NAME +#define SE_TIME_ZONE_NAME TEXT("SeTimeZonePrivilege") +#endif + +// +// The growth size for array of module handle entries +// +#define MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE 0x100 + +// +// Module handle entry structure +// +typedef struct { + CHAR8 *PdbPointer; + VOID *ModHandle; +} PDB_NAME_TO_MOD_HANDLE; + +// +// An Array to hold the module handles +// +PDB_NAME_TO_MOD_HANDLE *mPdbNameModHandleArray = NULL; +UINTN mPdbNameModHandleArraySize = 0; + +// +// Default information about where the FD is located. +// This array gets filled in with information from PcdWinNtFirmwareVolume +// The number of array elements is allocated base on parsing +// PcdWinNtFirmwareVolume and the memory is never freed. +// +UINTN gFdInfoCount = 0; +NT_FD_INFO *gFdInfo; + +// +// Array that supports separate memory ranges. +// The memory ranges are set by PcdWinNtMemorySizeForSecMain. +// The number of array elements is allocated base on parsing +// PcdWinNtMemorySizeForSecMain value and the memory is never freed. +// +UINTN gSystemMemoryCount = 0; +NT_SYSTEM_MEMORY *gSystemMemory; + +/*++ + +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. + It uses gSystemMemory[] and gSystemMemoryCount that were created by + parsing the host environment variable EFI_MEMORY_SIZE. + The size comes from the varaible and the address comes from the call to + UnixOpenFile. + +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 + +**/ +EFI_STATUS +WinPeiAutoScan ( + IN UINTN Index, + OUT EFI_PHYSICAL_ADDRESS *MemoryBase, + OUT UINT64 *MemorySize + ) +{ + if (Index >= gSystemMemoryCount) { + return EFI_UNSUPPORTED; + } + + // + // Allocate enough memory space for emulator + // + gSystemMemory[Index].Memory = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (gSystemMemory[Index].Size), MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (gSystemMemory[Index].Memory == 0) { + return EFI_OUT_OF_RESOURCES; + } + + *MemoryBase = gSystemMemory[Index].Memory; + *MemorySize = gSystemMemory[Index].Size; + + return EFI_SUCCESS; +} + +/*++ + +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 its 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 + +**/ +EFI_STATUS +WinFdAddress ( + IN UINTN Index, + IN OUT EFI_PHYSICAL_ADDRESS *FdBase, + IN OUT UINT64 *FdSize, + IN OUT EFI_PHYSICAL_ADDRESS *FixUp + ) +{ + if (Index >= gFdInfoCount) { + return EFI_UNSUPPORTED; + } + + + *FdBase = (EFI_PHYSICAL_ADDRESS)(UINTN)gFdInfo[Index].Address; + *FdSize = (UINT64)gFdInfo[Index].Size; + *FixUp = 0; + + if (*FdBase == 0 && *FdSize == 0) { + return EFI_UNSUPPORTED; + } + + if (Index == 0) { + // + // FD 0 has XIP code and well known PCD values + // If the memory buffer could not be allocated at the FD build address + // the Fixup is the difference. + // + *FixUp = *FdBase - PcdGet64 (PcdEmuFdBaseAddress); + } + + return EFI_SUCCESS; +} + +/*++ + +Routine Description: + Since the SEC is the only Unix program in stack it must export + an interface to do POSIX calls. gUnix is initialized in UnixThunk.c. + +Arguments: + InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL); + InterfaceBase - Address of the gUnix global + +Returns: + EFI_SUCCESS - Data returned + +**/ +VOID * +WinThunk ( + VOID + ) +{ + return &gEmuThunkProtocol; +} + + +EMU_THUNK_PPI mSecEmuThunkPpi = { + WinPeiAutoScan, + WinFdAddress, + WinThunk +}; + +VOID +SecPrint ( + CHAR8 *Format, + ... + ) +{ + va_list Marker; + UINTN CharCount; + CHAR8 Buffer[0x1000]; + + va_start (Marker, Format); + + _vsnprintf (Buffer, sizeof (Buffer), Format, Marker); + + va_end (Marker); + + CharCount = strlen (Buffer); + WriteFile ( + GetStdHandle (STD_OUTPUT_HANDLE), + Buffer, + (DWORD)CharCount, + (LPDWORD)&CharCount, + NULL + ); +} + +/*++ + +Routine Description: + Check to see if an address range is in the EFI GCD memory map. + + This is all of GCD for system memory passed to DXE Core. FV + mapping and other device mapped into system memory are not + inlcuded in the check. + +Arguments: + Index - Which memory region to use + MemoryBase - Return Base address of memory region + MemorySize - Return size in bytes of the memory region + +Returns: + TRUE - Address is in the EFI GCD memory map + FALSE - Address is NOT in memory map + +**/ +BOOLEAN +EfiSystemMemoryRange ( + IN VOID *MemoryAddress + ) +{ + UINTN Index; + EFI_PHYSICAL_ADDRESS MemoryBase; + + MemoryBase = (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryAddress; + for (Index = 0; Index < gSystemMemoryCount; Index++) { + if ((MemoryBase >= gSystemMemory[Index].Memory) && + (MemoryBase < (gSystemMemory[Index].Memory + gSystemMemory[Index].Size)) ) { + return TRUE; + } + } + + return FALSE; +} + + +EFI_STATUS +WinNtOpenFile ( + IN CHAR16 *FileName, OPTIONAL + IN UINT32 MapSize, + IN DWORD CreationDisposition, + IN OUT VOID **BaseAddress, + OUT UINTN *Length + ) +/*++ + +Routine Description: + Opens and memory maps a file using WinNt services. If *BaseAddress is non zero + the process will try and allocate the memory starting at BaseAddress. + +Arguments: + FileName - The name of the file to open and map + MapSize - The amount of the file to map in bytes + CreationDisposition - The flags to pass to CreateFile(). Use to create new files for + memory emulation, and exiting files for firmware volume emulation + BaseAddress - The base address of the mapped file in the user address space. + If *BaseAddress is 0, the new memory region is used. + If *BaseAddress is not 0, the request memory region is used for + the mapping of the file into the process space. + Length - The size of the mapped region in bytes + +Returns: + EFI_SUCCESS - The file was opened and mapped. + EFI_NOT_FOUND - FileName was not found in the current directory + EFI_DEVICE_ERROR - An error occurred attempting to map the opened file + +--*/ +{ + HANDLE NtFileHandle; + HANDLE NtMapHandle; + VOID *VirtualAddress; + UINTN FileSize; + + // + // Use Win API to open/create a file + // + NtFileHandle = INVALID_HANDLE_VALUE; + if (FileName != NULL) { + NtFileHandle = CreateFile ( + FileName, + GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, + FILE_SHARE_READ, + NULL, + CreationDisposition, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + if (NtFileHandle == INVALID_HANDLE_VALUE) { + return EFI_NOT_FOUND; + } + } + // + // Map the open file into a memory range + // + NtMapHandle = CreateFileMapping ( + NtFileHandle, + NULL, + PAGE_EXECUTE_READWRITE, + 0, + MapSize, + NULL + ); + if (NtMapHandle == NULL) { + return EFI_DEVICE_ERROR; + } + // + // Get the virtual address (address in the emulator) of the mapped file + // + VirtualAddress = MapViewOfFileEx ( + NtMapHandle, + FILE_MAP_EXECUTE | FILE_MAP_ALL_ACCESS, + 0, + 0, + MapSize, + *BaseAddress + ); + if (VirtualAddress == NULL) { + return EFI_DEVICE_ERROR; + } + + if (MapSize == 0) { + // + // Seek to the end of the file to figure out the true file size. + // + FileSize = SetFilePointer ( + NtFileHandle, + 0, + NULL, + FILE_END + ); + if (FileSize == -1) { + return EFI_DEVICE_ERROR; + } + + *Length = FileSize; + } else { + *Length = MapSize; + } + + *BaseAddress = VirtualAddress; + + return EFI_SUCCESS; +} + +INTN +EFIAPI +main ( + IN INT Argc, + IN CHAR8 **Argv, + IN CHAR8 **Envp + ) +/*++ + +Routine Description: + Main entry point to SEC for WinNt. This is a Windows program + +Arguments: + Argc - Number of command line arguments + Argv - Array of command line argument strings + Envp - Array of environment variable strings + +Returns: + 0 - Normal exit + 1 - Abnormal exit + +--*/ +{ + EFI_STATUS Status; + HANDLE Token; + TOKEN_PRIVILEGES TokenPrivileges; + VOID *TemporaryRam; + UINT32 TemporaryRamSize; + VOID *EmuMagicPage; + UINTN Index; + UINTN Index1; + CHAR16 *FileName; + CHAR16 *FileNamePtr; + BOOLEAN Done; + EFI_PEI_FILE_HANDLE FileHandle; + VOID *SecFile; + CHAR16 *MemorySizeStr; + CHAR16 *FirmwareVolumesStr; + UINTN ProcessAffinityMask; + UINTN SystemAffinityMask; + INT32 LowBit; + + // + // Enable the privilege so that RTC driver can successfully run SetTime() + // + OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &Token); + if (LookupPrivilegeValue(NULL, SE_TIME_ZONE_NAME, &TokenPrivileges.Privileges[0].Luid)) { + TokenPrivileges.PrivilegeCount = 1; + TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + AdjustTokenPrivileges(Token, FALSE, &TokenPrivileges, 0, (PTOKEN_PRIVILEGES) NULL, 0); + } + + MemorySizeStr = (CHAR16 *) PcdGetPtr (PcdEmuMemorySize); + FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdEmuFirmwareVolume); + + SecPrint ("\n\rEDK II WIN Host Emulation Environment from http://www.tianocore.org/edk2/\n\r"); + + // + // Determine the first thread available to this process. + // + if (GetProcessAffinityMask (GetCurrentProcess (), &ProcessAffinityMask, &SystemAffinityMask)) { + LowBit = (INT32)LowBitSet32 ((UINT32)ProcessAffinityMask); + if (LowBit != -1) { + // + // Force the system to bind the process to a single thread to work + // around odd semaphore type crashes. + // + SetProcessAffinityMask (GetCurrentProcess (), (INTN)(BIT0 << LowBit)); + } + } + + // + // Make some Windows calls to Set the process to the highest priority in the + // idle class. We need this to have good performance. + // + SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS); + SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST); + + SecInitializeThunk (); + // + // PPIs pased into PEI_CORE + // + AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI, &gEmuThunkPpiGuid, &mSecEmuThunkPpi); + + // + // Emulator Bus Driver Thunks + // + AddThunkProtocol (&mWinNtWndThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuGop), TRUE); + AddThunkProtocol (&mWinNtFileSystemThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuFileSystem), TRUE); + AddThunkProtocol (&mWinNtBlockIoThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuVirtualDisk), TRUE); + AddThunkProtocol (&mWinNtSnpThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuNetworkInterface), TRUE); + + // + // Allocate space for gSystemMemory Array + // + gSystemMemoryCount = CountSeparatorsInString (MemorySizeStr, '!') + 1; + gSystemMemory = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY)); + if (gSystemMemory == NULL) { + SecPrint ("ERROR : Can not allocate memory for %S. Exiting.\n\r", MemorySizeStr); + exit (1); + } + + // + // Allocate space for gSystemMemory Array + // + gFdInfoCount = CountSeparatorsInString (FirmwareVolumesStr, '!') + 1; + gFdInfo = calloc (gFdInfoCount, sizeof (NT_FD_INFO)); + if (gFdInfo == NULL) { + SecPrint ("ERROR : Can not allocate memory for %S. Exiting.\n\r", FirmwareVolumesStr); + exit (1); + } + // + // Setup Boot Mode. + // + SecPrint (" BootMode 0x%02x\n\r", PcdGet32 (PcdEmuBootMode)); + + // + // Allocate 128K memory to emulate temp memory for PEI. + // on a real platform this would be SRAM, or using the cache as RAM. + // Set TemporaryRam to zero so WinNtOpenFile will allocate a new mapping + // + TemporaryRamSize = TEMPORARY_RAM_SIZE; + TemporaryRam = VirtualAlloc (NULL, (SIZE_T) (TemporaryRamSize), MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (TemporaryRam == NULL) { + SecPrint ("ERROR : Can not allocate enough space for SecStack\n\r"); + exit (1); + } + SetMem32 (TemporaryRam, TemporaryRamSize, PcdGet32 (PcdInitValueInTempStack)); + + SecPrint (" OS Emulator passing in %u KB of temp RAM at 0x%08lx to SEC\n\r", + TemporaryRamSize / SIZE_1KB, + TemporaryRam + ); + + // + // If enabled use the magic page to communicate between modules + // This replaces the PI PeiServicesTable pointer mechanism that + // deos not work in the emulator. It also allows the removal of + // writable globals from SEC, PEI_CORE (libraries), PEIMs + // + EmuMagicPage = (VOID *)(UINTN)(FixedPcdGet64 (PcdPeiServicesTablePage) & MAX_UINTN); + if (EmuMagicPage != NULL) { + UINT64 Size; + Status = WinNtOpenFile ( + NULL, + SIZE_4KB, + 0, + &EmuMagicPage, + &Size + ); + if (EFI_ERROR (Status)) { + SecPrint ("ERROR : Could not allocate PeiServicesTablePage @ %p\n\r", EmuMagicPage); + return EFI_DEVICE_ERROR; + } + } + + // + // Open All the firmware volumes and remember the info in the gFdInfo global + // Meanwhile, find the SEC Core. + // + FileNamePtr = AllocateCopyPool (StrSize (FirmwareVolumesStr), FirmwareVolumesStr); + if (FileNamePtr == NULL) { + SecPrint ("ERROR : Can not allocate memory for firmware volume string\n\r"); + exit (1); + } + + for (Done = FALSE, Index = 0, SecFile = NULL; !Done; Index++) { + FileName = FileNamePtr; + for (Index1 = 0; (FileNamePtr[Index1] != '!') && (FileNamePtr[Index1] != 0); Index1++) + ; + if (FileNamePtr[Index1] == 0) { + Done = TRUE; + } else { + FileNamePtr[Index1] = '\0'; + FileNamePtr = &FileNamePtr[Index1 + 1]; + } + + // + // Open the FD and remember where it got mapped into our processes address space + // + Status = WinNtOpenFile ( + FileName, + 0, + OPEN_EXISTING, + &gFdInfo[Index].Address, + &gFdInfo[Index].Size + ); + if (EFI_ERROR (Status)) { + SecPrint ("ERROR : Can not open Firmware Device File %S (0x%X). Exiting.\n\r", FileName, Status); + exit (1); + } + + SecPrint (" FD loaded from %S", FileName); + + if (SecFile == NULL) { + // + // Assume the beginning of the FD is an FV and look for the SEC Core. + // Load the first one we find. + // + FileHandle = NULL; + Status = PeiServicesFfsFindNextFile ( + EFI_FV_FILETYPE_SECURITY_CORE, + (EFI_PEI_FV_HANDLE)gFdInfo[Index].Address, + &FileHandle + ); + if (!EFI_ERROR (Status)) { + Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SecFile); + if (!EFI_ERROR (Status)) { + SecPrint (" contains SEC Core"); + } + } + } + + SecPrint ("\n\r"); + } + // + // Calculate memory regions and store the information in the gSystemMemory + // global for later use. The autosizing code will use this data to + // map this memory into the SEC process memory space. + // + for (Index = 0, Done = FALSE; !Done; Index++) { + // + // Save the size of the memory and make a Unicode filename SystemMemory00, ... + // + gSystemMemory[Index].Size = ((UINT64)_wtoi (MemorySizeStr)) * ((UINT64)SIZE_1MB); + + // + // Find the next region + // + for (Index1 = 0; MemorySizeStr[Index1] != '!' && MemorySizeStr[Index1] != 0; Index1++) + ; + if (MemorySizeStr[Index1] == 0) { + Done = TRUE; + } + + MemorySizeStr = MemorySizeStr + Index1 + 1; + } + + SecPrint ("\n\r"); + + // + // Hand off to SEC Core + // + SecLoadSecCore ((UINTN)TemporaryRam, TemporaryRamSize, gFdInfo[0].Address, gFdInfo[0].Size, SecFile); + + // + // If we get here, then the SEC Core returned. This is an error as SEC should + // always hand off to PEI Core and then on to DXE Core. + // + SecPrint ("ERROR : SEC returned\n\r"); + exit (1); +} + +VOID +SecLoadSecCore ( + IN UINTN TemporaryRam, + IN UINTN TemporaryRamSize, + IN VOID *BootFirmwareVolumeBase, + IN UINTN BootFirmwareVolumeSize, + IN VOID *SecCorePe32File + ) +/*++ + +Routine Description: + This is the service to load the SEC Core from the Firmware Volume + +Arguments: + TemporaryRam - Memory to use for SEC. + TemporaryRamSize - Size of Memory to use for SEC + BootFirmwareVolumeBase - Start of the Boot FV + SecCorePe32File - SEC Core PE32 + +Returns: + Success means control is transferred and thus we should never return + +--*/ +{ + EFI_STATUS Status; + VOID *TopOfStack; + VOID *SecCoreEntryPoint; + EFI_SEC_PEI_HAND_OFF *SecCoreData; + UINTN SecStackSize; + + // + // Compute Top Of Memory for Stack and PEI Core Allocations + // + SecStackSize = TemporaryRamSize >> 1; + + // + // |-----------| <---- TemporaryRamBase + TemporaryRamSize + // | Heap | + // | | + // |-----------| <---- StackBase / PeiTemporaryMemoryBase + // | | + // | Stack | + // |-----------| <---- TemporaryRamBase + // + TopOfStack = (VOID *)(TemporaryRam + SecStackSize); + + // + // Reservet space for storing PeiCore's parament in stack. + // + TopOfStack = (VOID *)((UINTN)TopOfStack - sizeof (EFI_SEC_PEI_HAND_OFF) - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + // + // Bind this information into the SEC hand-off state + // + SecCoreData = (EFI_SEC_PEI_HAND_OFF*)(UINTN)TopOfStack; + SecCoreData->DataSize = sizeof (EFI_SEC_PEI_HAND_OFF); + SecCoreData->BootFirmwareVolumeBase = BootFirmwareVolumeBase; + SecCoreData->BootFirmwareVolumeSize = BootFirmwareVolumeSize; + SecCoreData->TemporaryRamBase = (VOID*)TemporaryRam; + SecCoreData->TemporaryRamSize = TemporaryRamSize; + SecCoreData->StackBase = SecCoreData->TemporaryRamBase; + SecCoreData->StackSize = SecStackSize; + SecCoreData->PeiTemporaryRamBase = (VOID*) ((UINTN) SecCoreData->TemporaryRamBase + SecStackSize); + SecCoreData->PeiTemporaryRamSize = TemporaryRamSize - SecStackSize; + + // + // Load the PEI Core from a Firmware Volume + // + Status = SecPeCoffGetEntryPoint ( + SecCorePe32File, + &SecCoreEntryPoint + ); + if (EFI_ERROR (Status)) { + return ; + } + + // + // Transfer control to the SEC Core + // + SwitchStack ( + (SWITCH_STACK_ENTRY_POINT)(UINTN)SecCoreEntryPoint, + SecCoreData, + GetThunkPpiList (), + TopOfStack + ); + // + // If we get here, then the SEC Core returned. This is an error + // + return ; +} + +RETURN_STATUS +EFIAPI +SecPeCoffGetEntryPoint ( + IN VOID *Pe32Data, + IN OUT VOID **EntryPoint + ) +{ + EFI_STATUS Status; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + + ZeroMem (&ImageContext, sizeof (ImageContext)); + ImageContext.Handle = Pe32Data; + + ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) SecImageRead; + + Status = PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Allocate space in NT (not emulator) memory with ReadWrite and Execute attribute. + // Extra space is for alignment + // + ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)), MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (ImageContext.ImageAddress == 0) { + return EFI_OUT_OF_RESOURCES; + } + // + // Align buffer on section boundary + // + ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; + ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1); + + Status = PeCoffLoaderLoadImage (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = PeCoffLoaderRelocateImage (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + + *EntryPoint = (VOID *)(UINTN)ImageContext.EntryPoint; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +SecImageRead ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ) +/*++ + +Routine Description: + Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file + +Arguments: + FileHandle - The handle to the PE/COFF file + FileOffset - The offset, in bytes, into the file to read + ReadSize - The number of bytes to read from the file starting at FileOffset + Buffer - A pointer to the buffer to read the data into. + +Returns: + EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset + +--*/ +{ + CHAR8 *Destination8; + CHAR8 *Source8; + UINTN Length; + + Destination8 = Buffer; + Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); + Length = *ReadSize; + while (Length--) { + *(Destination8++) = *(Source8++); + } + + return EFI_SUCCESS; +} + +CHAR16 * +AsciiToUnicode ( + IN CHAR8 *Ascii, + IN UINTN *StrLen OPTIONAL + ) +/*++ + +Routine Description: + Convert the passed in Ascii string to Unicode. + Optionally return the length of the strings. + +Arguments: + Ascii - Ascii string to convert + StrLen - Length of string + +Returns: + Pointer to malloc'ed Unicode version of Ascii + +--*/ +{ + UINTN Index; + CHAR16 *Unicode; + + // + // Allocate a buffer for unicode string + // + for (Index = 0; Ascii[Index] != '\0'; Index++) + ; + Unicode = malloc ((Index + 1) * sizeof (CHAR16)); + if (Unicode == NULL) { + return NULL; + } + + for (Index = 0; Ascii[Index] != '\0'; Index++) { + Unicode[Index] = (CHAR16) Ascii[Index]; + } + + Unicode[Index] = '\0'; + + if (StrLen != NULL) { + *StrLen = Index; + } + + return Unicode; +} + +UINTN +CountSeparatorsInString ( + IN CONST CHAR16 *String, + IN CHAR16 Separator + ) +/*++ + +Routine Description: + Count the number of separators in String + +Arguments: + String - String to process + Separator - Item to count + +Returns: + Number of Separator in String + +--*/ +{ + UINTN Count; + + for (Count = 0; *String != '\0'; String++) { + if (*String == Separator) { + Count++; + } + } + + return Count; +} + +/** + Store the ModHandle in an array indexed by the Pdb File name. + The ModHandle is needed to unload the image. + @param ImageContext - Input data returned from PE Laoder Library. Used to find the + .PDB file name of the PE Image. + @param ModHandle - Returned from LoadLibraryEx() and stored for call to + FreeLibrary(). + @return return EFI_SUCCESS when ModHandle was stored. +--*/ +EFI_STATUS +AddModHandle ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN VOID *ModHandle + ) + +{ + UINTN Index; + PDB_NAME_TO_MOD_HANDLE *Array; + UINTN PreviousSize; + PDB_NAME_TO_MOD_HANDLE *TempArray; + HANDLE Handle; + UINTN Size; + + // + // Return EFI_ALREADY_STARTED if this DLL has already been loaded + // + Array = mPdbNameModHandleArray; + for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) { + if (Array->PdbPointer != NULL && Array->ModHandle == ModHandle) { + return EFI_ALREADY_STARTED; + } + } + + Array = mPdbNameModHandleArray; + for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) { + if (Array->PdbPointer == NULL) { + // + // Make a copy of the stirng and store the ModHandle + // + Handle = GetProcessHeap (); + Size = AsciiStrLen (ImageContext->PdbPointer) + 1; + Array->PdbPointer = HeapAlloc ( Handle, HEAP_ZERO_MEMORY, Size); + ASSERT (Array->PdbPointer != NULL); + + AsciiStrCpyS (Array->PdbPointer, Size, ImageContext->PdbPointer); + Array->ModHandle = ModHandle; + return EFI_SUCCESS; + } + } + + // + // No free space in mPdbNameModHandleArray so grow it by + // MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE entires. + // + PreviousSize = mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE); + mPdbNameModHandleArraySize += MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE; + // + // re-allocate a new buffer and copy the old values to the new locaiton. + // + TempArray = HeapAlloc (GetProcessHeap (), + HEAP_ZERO_MEMORY, + mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE) + ); + + CopyMem ((VOID *) (UINTN) TempArray, (VOID *) (UINTN)mPdbNameModHandleArray, PreviousSize); + + HeapFree (GetProcessHeap (), 0, mPdbNameModHandleArray); + + mPdbNameModHandleArray = TempArray; + if (mPdbNameModHandleArray == NULL) { + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + + return AddModHandle (ImageContext, ModHandle); +} + +/** + Return the ModHandle and delete the entry in the array. + @param ImageContext - Input data returned from PE Laoder Library. Used to find the + .PDB file name of the PE Image. + @return + ModHandle - ModHandle assoicated with ImageContext is returned + NULL - No ModHandle associated with ImageContext +**/ +VOID * +RemoveModHandle ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + UINTN Index; + PDB_NAME_TO_MOD_HANDLE *Array; + + if (ImageContext->PdbPointer == NULL) { + // + // If no PDB pointer there is no ModHandle so return NULL + // + return NULL; + } + + Array = mPdbNameModHandleArray; + for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) { + if ((Array->PdbPointer != NULL) && (AsciiStrCmp(Array->PdbPointer, ImageContext->PdbPointer) == 0)) { + // + // If you find a match return it and delete the entry + // + HeapFree (GetProcessHeap (), 0, Array->PdbPointer); + Array->PdbPointer = NULL; + return Array->ModHandle; + } + } + + return NULL; +} + +VOID +EFIAPI +PeCoffLoaderRelocateImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + EFI_STATUS Status; + VOID *DllEntryPoint; + CHAR16 *DllFileName; + HMODULE Library; + UINTN Index; + + ASSERT (ImageContext != NULL); + // + // If we load our own PE COFF images the Windows debugger can not source + // level debug our code. If a valid PDB pointer exists use it to load + // the *.dll file as a library using Windows* APIs. This allows + // source level debug. The image is still loaded and relocated + // in the Framework memory space like on a real system (by the code above), + // but the entry point points into the DLL loaded by the code below. + // + + DllEntryPoint = NULL; + + // + // Load the DLL if it's not an EBC image. + // + if ((ImageContext->PdbPointer != NULL) && + (ImageContext->Machine != EFI_IMAGE_MACHINE_EBC)) { + // + // Convert filename from ASCII to Unicode + // + DllFileName = AsciiToUnicode (ImageContext->PdbPointer, &Index); + + // + // Check that we have a valid filename + // + if (Index < 5 || DllFileName[Index - 4] != '.') { + free (DllFileName); + + // + // Never return an error if PeCoffLoaderRelocateImage() succeeded. + // The image will run, but we just can't source level debug. If we + // return an error the image will not run. + // + return; + } + // + // Replace .PDB with .DLL on the filename + // + DllFileName[Index - 3] = 'D'; + DllFileName[Index - 2] = 'L'; + DllFileName[Index - 1] = 'L'; + + // + // Load the .DLL file into the user process's address space for source + // level debug + // + Library = LoadLibraryEx (DllFileName, NULL, DONT_RESOLVE_DLL_REFERENCES); + if (Library != NULL) { + // + // InitializeDriver is the entry point we put in all our EFI DLL's. The + // DONT_RESOLVE_DLL_REFERENCES argument to LoadLIbraryEx() suppresses the + // normal DLL entry point of DllMain, and prevents other modules that are + // referenced in side the DllFileName from being loaded. There is no error + // checking as the we can point to the PE32 image loaded by Tiano. This + // step is only needed for source level debugging + // + DllEntryPoint = (VOID *) (UINTN) GetProcAddress (Library, "InitializeDriver"); + + } + + if ((Library != NULL) && (DllEntryPoint != NULL)) { + Status = AddModHandle (ImageContext, Library); + if (Status == EFI_ALREADY_STARTED) { + // + // If the DLL has already been loaded before, then this instance of the DLL can not be debugged. + // + ImageContext->PdbPointer = NULL; + SecPrint ("WARNING: DLL already loaded. No source level debug %S.\n\r", DllFileName); + } else { + // + // This DLL is not already loaded, so source level debugging is supported. + // + ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) DllEntryPoint; + SecPrint ("LoadLibraryEx (\n\r %S,\n\r NULL, DONT_RESOLVE_DLL_REFERENCES)\n\r", DllFileName); + } + } else { + SecPrint ("WARNING: No source level debug %S. \n\r", DllFileName); + } + + free (DllFileName); + } +} + +VOID +EFIAPI +PeCoffLoaderUnloadImageExtraAction ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext +) +{ + VOID *ModHandle; + + ASSERT (ImageContext != NULL); + + ModHandle = RemoveModHandle (ImageContext); + if (ModHandle != NULL) { + FreeLibrary (ModHandle); + SecPrint ("FreeLibrary (\n\r %s)\n\r", ImageContext->PdbPointer); + } else { + SecPrint ("WARNING: Unload image without source level debug\n\r"); + } +} + +VOID +_ModuleEntryPoint ( + VOID + ) +{ +} diff --git a/CdeEmuPkg/EmulatorPkg/Win/Host/WinHost.h b/CdeEmuPkg/EmulatorPkg/Win/Host/WinHost.h new file mode 100644 index 00000000000..bce56cdc2f9 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/Host/WinHost.h @@ -0,0 +1,208 @@ +/**@file + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+(C) Copyright 2020 Hewlett Packard Enterprise Development LP
+SPDX-License-Identifier: BSD-2-Clause-Patent + + +Module Name: + WinHost.h + +Abstract: + Include file for Windows Host + +**/ +#ifndef _HOST_H_ +#define _HOST_H_ + +#include +#include +#include "WinInclude.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define TEMPORARY_RAM_SIZE 0x20000 + +typedef struct { + VOID *Address; + UINTN Size; +} NT_FD_INFO; + +typedef struct { + EFI_PHYSICAL_ADDRESS Memory; + UINT64 Size; +} NT_SYSTEM_MEMORY; + +RETURN_STATUS +EFIAPI +SecPeCoffGetEntryPoint ( + IN VOID *Pe32Data, + IN OUT VOID **EntryPoint +); + +VOID +SecLoadSecCore ( + IN UINTN TemporaryRam, + IN UINTN TemporaryRamSize, + IN VOID *BootFirmwareVolumeBase, + IN UINTN BootFirmwareVolumeSize, + IN VOID *SecCorePe32File +) +/*++ + +Routine Description: + This is the service to load the SEC Core from the Firmware Volume + +Arguments: + TemporaryRam - Memory to use for SEC. + TemporaryRamSize - Size of Memory to use for SEC + BootFirmwareVolumeBase - Start of the Boot FV + SecCorePe32File - SEC Core PE32 + +Returns: + Success means control is transferred and thus we should never return + +--*/ +; + +EFI_STATUS +EFIAPI +SecWinNtFdAddress ( + IN UINTN Index, + IN OUT EFI_PHYSICAL_ADDRESS *FdBase, + IN OUT UINT64 *FdSize + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Index - TODO: add argument description + FdBase - TODO: add argument description + FdSize - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + + +EFI_STATUS +EFIAPI +SecImageRead ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + FileHandle - TODO: add argument description + FileOffset - TODO: add argument description + ReadSize - TODO: add argument description + Buffer - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +CHAR16 * +AsciiToUnicode ( + IN CHAR8 *Ascii, + IN UINTN *StrLen OPTIONAL + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + Ascii - TODO: add argument description + StrLen - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +UINTN +CountSeparatorsInString ( + IN CONST CHAR16 *String, + IN CHAR16 Separator + ) +/*++ + +Routine Description: + + TODO: Add function description + +Arguments: + + String - TODO: add argument description + Separator - TODO: add argument description + +Returns: + + TODO: add return values + +--*/ +; + +BOOLEAN +EfiSystemMemoryRange ( + IN VOID *MemoryAddress + ); +VOID +SecInitializeThunk ( + VOID +); +extern EMU_THUNK_PROTOCOL gEmuThunkProtocol; +extern EMU_IO_THUNK_PROTOCOL mWinNtWndThunkIo; +extern EMU_IO_THUNK_PROTOCOL mWinNtFileSystemThunkIo; +extern EMU_IO_THUNK_PROTOCOL mWinNtBlockIoThunkIo; +extern EMU_IO_THUNK_PROTOCOL mWinNtSnpThunkIo; + +#endif diff --git a/CdeEmuPkg/EmulatorPkg/Win/Host/WinHost.inf b/CdeEmuPkg/EmulatorPkg/Win/Host/WinHost.inf new file mode 100644 index 00000000000..2fb7c105fd3 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/Host/WinHost.inf @@ -0,0 +1,110 @@ +## @file +# Entry Point of Win Emulator +# +# Main executable file of Win Emulator that loads Sec core after initialization finished. +# Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = WinHost + FILE_GUID = 62E8F833-2B0A-4C19-A966-63C180588BE7 + MODULE_TYPE = USER_DEFINED + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + WinMemoryAllocationLib.c + WinGopInput.c + WinGopScreen.c + WinGop.h + WinFileSystem.c + WinBlockIo.c + WinThunk.c + WinHost.h + WinHost.c + WinPacketFilter.c + WinInclude.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + NetworkPkg/NetworkPkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + DebugLib + PcdLib + PrintLib + BaseMemoryLib + BaseLib + PeCoffLib + ThunkPpiList + ThunkProtocolList + PpiListLib + PeiServicesLib + FrameBufferBltLib + +[Ppis] + gEmuThunkPpiGuid + +[Protocols] + gEmuIoThunkProtocolGuid + gEmuGraphicsWindowProtocolGuid + gEmuBlockIoProtocolGuid + gEfiSimpleFileSystemProtocolGuid + gEmuSnpProtocolGuid + +[Guids] + gEfiFileSystemVolumeLabelInfoIdGuid # SOMETIMES_CONSUMED + gEfiFileInfoGuid # SOMETIMES_CONSUMED + gEfiFileSystemInfoGuid # SOMETIMES_CONSUMED + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack + + gEmulatorPkgTokenSpaceGuid.PcdEmuBootMode + gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareVolume + gEmulatorPkgTokenSpaceGuid.PcdEmuMemorySize + gEmulatorPkgTokenSpaceGuid.PcdEmuFdBaseAddress + gEmulatorPkgTokenSpaceGuid.PcdEmuVirtualDisk + gEmulatorPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window" + gEmulatorPkgTokenSpaceGuid.PcdEmuFileSystem + gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage + gEmulatorPkgTokenSpaceGuid.PcdEmuNetworkInterface|L"0" + +[BuildOptions] + MSFT:*_*_*_DLINK_FLAGS == /out:"$(BIN_DIR)\$(BASE_NAME).exe" /base:0x10000000 /pdb:"$(BIN_DIR)\$(BASE_NAME).pdb" + MSFT:*_*_*_CC_FLAGS = /nologo /W4 /WX /Gy /c /D UNICODE /Od /Oy- /FIAutoGen.h /EHs-c- /GF /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE + MSFT:*_*_*_PP_FLAGS == /nologo /E /TC /FIAutoGen.h + + MSFT:*_VS2015_IA32_DLINK_FLAGS = /LIBPATH:"%VS2015_PREFIX%Lib" /LIBPATH:"%VS2015_PREFIX%VC\Lib" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib vcruntimed.lib ucrtd.lib + MSFT:*_VS2015x86_IA32_DLINK_FLAGS = /LIBPATH:"%VS2015_PREFIX%Lib" /LIBPATH:"%VS2015_PREFIX%VC\Lib" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib vcruntimed.lib ucrtd.lib + MSFT:*_VS2017_IA32_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x86" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_VS2019_IA32_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x86" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_*_IA32_ASM_FLAGS == /nologo /W3 /WX /c /coff /Cx /Zd /W0 /Zi + MSFT:*_*_IA32_ASMLINK_FLAGS == /link /nologo /tiny + + MSFT:*_VS2015_X64_DLINK_FLAGS = /LIBPATH:"%VS2015_PREFIX%VC\Lib\AMD64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_VS2015x86_X64_DLINK_FLAGS = /LIBPATH:"%VS2015_PREFIX%VC\Lib\AMD64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_VS2017_X64_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_VS2019_X64_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_*_X64_ASM_FLAGS == /nologo /W3 /WX /c /Cx /Zd /W0 /Zi + MSFT:*_*_X64_ASMLINK_FLAGS == /link /nologo + + GCC:*_CLANGPDB_X64_DLINK_FLAGS == /out:"$(BIN_DIR)\$(BASE_NAME).exe" /base:0x10000000 /pdb:"$(BIN_DIR)\$(BASE_NAME).pdb" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /LIBPATH:"%VCToolsInstallDir%lib\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /OPT:REF /DEBUG /MACHINE:AMD64 Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib /lldmap /EXPORT:InitializeDriver=_ModuleEntryPoint + GCC:*_CLANGPDB_X64_CC_FLAGS == -m64 -g -fshort-wchar -fno-strict-aliasing -Wall -c -include AutoGen.h -D _CRT_SECURE_NO_WARNINGS -Wnonportable-include-path -D UNICODE -D _CRT_SECURE_NO_DEPRECATE + + GCC:*_CLANGPDB_IA32_DLINK_FLAGS == /out:"$(BIN_DIR)\$(BASE_NAME).exe" /base:0x10000000 /pdb:"$(BIN_DIR)\$(BASE_NAME).pdb" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /LIBPATH:"%VCToolsInstallDir%ib\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /OPT:REF /DEBUG /MACHINE:I386 Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib /lldmap /EXPORT:InitializeDriver=_ModuleEntryPoint + GCC:*_CLANGPDB_IA32_CC_FLAGS == -m32 -g -fshort-wchar -fno-strict-aliasing -Wall -c -include AutoGen.h -D _CRT_SECURE_NO_WARNINGS -Wnonportable-include-path -D UNICODE -D _CRT_SECURE_NO_DEPRECATE diff --git a/CdeEmuPkg/EmulatorPkg/Win/Host/WinInclude.h b/CdeEmuPkg/EmulatorPkg/Win/Host/WinInclude.h new file mode 100644 index 00000000000..3d9bd48d16d --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/Host/WinInclude.h @@ -0,0 +1,70 @@ +/**@file + Public include file for the WinNt Library + +Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef __WIN_NT_INCLUDE_H__ +#define __WIN_NT_INCLUDE_H__ + +// +// Win32 include files do not compile clean with /W4, so we use the warning +// pragma to suppress the warnings for Win32 only. This way our code can stil +// compile at /W4 (highest warning level) with /WX (warnings cause build +// errors). +// +#pragma warning(disable : 4115) +#pragma warning(disable : 4201) +#pragma warning(disable : 4028) +#pragma warning(disable : 4133) + +#define GUID _WINNT_DUP_GUID_____ +#define _LIST_ENTRY _WINNT_DUP_LIST_ENTRY_FORWARD +#define LIST_ENTRY _WINNT_DUP_LIST_ENTRY +#if defined (MDE_CPU_IA32) && (_MSC_VER < 1800) +#define InterlockedIncrement _WINNT_DUP_InterlockedIncrement +#define InterlockedDecrement _WINNT_DUP_InterlockedDecrement +#define InterlockedCompareExchange64 _WINNT_DUP_InterlockedCompareExchange64 +#endif +#undef UNALIGNED +#undef CONST +#undef VOID +#undef DEBUG_EVENT + +// WQBugBug: This typedef is to make "windows.h" buildable. +// It should be removed after the root cause why +// size_t is undefined when go into the line below is found. +#if defined (MDE_CPU_IA32) +typedef UINT32 size_t ; +#endif + +#include "windows.h" +#include "windowsx.h" + +#undef GUID +#undef _LIST_ENTRY +#undef LIST_ENTRY +#undef InterlockedIncrement +#undef InterlockedDecrement +#undef InterlockedCompareExchange64 +#undef InterlockedCompareExchangePointer +#undef CreateEventEx + +#define VOID void + +// +// Prevent collisions with Windows API name macros that deal with Unicode/Not issues +// +#undef LoadImage +#undef CreateEvent +#undef FAR + +// +// Set the warnings back on as the EFI code must be /W4. +// +#pragma warning(default : 4115) +#pragma warning(default : 4201) + + +#endif diff --git a/CdeEmuPkg/EmulatorPkg/Win/Host/WinMemoryAllocationLib.c b/CdeEmuPkg/EmulatorPkg/Win/Host/WinMemoryAllocationLib.c new file mode 100644 index 00000000000..ed78d1e0e74 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/Host/WinMemoryAllocationLib.c @@ -0,0 +1,172 @@ +/*++ @file + + Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +#include + +/** + Allocates a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocatePool ( + IN UINTN AllocationSize + ) +{ + return (VOID*) malloc (AllocationSize); +} + + +/** + Allocates and zeros a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateZeroPool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = AllocatePool (AllocationSize); + if (Buffer == NULL) { + return NULL; + } + + ZeroMem (Buffer, AllocationSize); + + return Buffer; +} + + +/** + Reallocates a buffer of type EfiBootServicesData. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocatePool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + VOID *NewBuffer; + + NewBuffer = AllocatePool (NewSize); + if (NewBuffer == NULL) { + return NULL; + } + + if (OldBuffer != NULL) { + if (OldSize > 0) { + CopyMem (NewBuffer, OldBuffer, OldSize); + } + + FreePool (OldBuffer); + } + + return NewBuffer; +} + +/** + Copies a buffer to an allocated buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + VOID *Memory; + + Memory = AllocatePool (AllocationSize); + if (Memory != NULL) { + Memory = CopyMem (Memory, Buffer, AllocationSize); + } + return Memory; +} + + +/** + Frees a buffer that was previously allocated with one of the pool allocation functions in the + Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + pool allocation services of the Memory Allocation Library. If it is not possible to free pool + resources, then this function will perform no actions. + + If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, + then ASSERT(). + + @param Buffer Pointer to the buffer to free. + +**/ +VOID +EFIAPI +FreePool ( + IN VOID *Buffer + ) +{ + free ((void *) Buffer); +} + diff --git a/CdeEmuPkg/EmulatorPkg/Win/Host/WinPacketFilter.c b/CdeEmuPkg/EmulatorPkg/Win/Host/WinPacketFilter.c new file mode 100644 index 00000000000..ffba8cd4608 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/Host/WinPacketFilter.c @@ -0,0 +1,1135 @@ +/**@file + Windows Packet Filter implementation of the EMU_SNP_PROTOCOL that allows the + emulator to get on real networks. + +Copyright (c) 2004 - 2009, 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 + +**/ +#include "WinHost.h" + +#define NETWORK_LIBRARY_NAME_U L"SnpNt32Io.dll" +#define NETWORK_LIBRARY_INITIALIZE "SnpInitialize" +#define NETWORK_LIBRARY_FINALIZE "SnpFinalize" +#define NETWORK_LIBRARY_SET_RCV_FILTER "SnpSetReceiveFilter" +#define NETWORK_LIBRARY_RECEIVE "SnpReceive" +#define NETWORK_LIBRARY_TRANSMIT "SnpTransmit" + +#pragma pack(1) +typedef struct _NT_NET_INTERFACE_INFO { + UINT32 InterfaceIndex; + EFI_MAC_ADDRESS MacAddr; +} NT_NET_INTERFACE_INFO; +#pragma pack() + +#define NET_ETHER_HEADER_SIZE 14 +#define MAX_INTERFACE_INFO_NUMBER 16 +#define SNP_MAX_TX_BUFFER_NUM 65536 +#define SNP_TX_BUFFER_INCREASEMENT 32 +#define DEFAULT_SELECTED_NIC_INDEX 0 + +// +// Functions in Net Library +// +typedef +INT32 +(*NT_NET_INITIALIZE) ( + IN OUT UINT32 *InterfaceCount, + IN OUT NT_NET_INTERFACE_INFO * InterfaceInfoBuffer + ); + +typedef +INT32 +(*NT_NET_FINALIZE) ( + VOID + ); + +typedef +INT32 +(*NT_NET_SET_RECEIVE_FILTER) ( + IN UINT32 Index, + IN UINT32 EnableFilter, + IN UINT32 MCastFilterCnt, + IN EFI_MAC_ADDRESS * MCastFilter + ); + +typedef +INT32 +(*NT_NET_RECEIVE) ( + IN UINT32 Index, + IN OUT UINT32 *BufferSize, + OUT VOID *Buffer + ); + +typedef +INT32 +(*NT_NET_TRANSMIT) ( + IN UINT32 Index, + IN UINT32 HeaderSize, + IN UINT32 BufferSize, + IN VOID *Buffer, + IN EFI_MAC_ADDRESS * SrcAddr, + IN EFI_MAC_ADDRESS * DestAddr, + IN UINT16 *Protocol + ); + +typedef struct _NT_NET_UTILITY_TABLE { + NT_NET_INITIALIZE Initialize; + NT_NET_FINALIZE Finalize; + NT_NET_SET_RECEIVE_FILTER SetReceiveFilter; + NT_NET_RECEIVE Receive; + NT_NET_TRANSMIT Transmit; +} NT_NET_UTILITY_TABLE; + +// +// Instance data for each fake SNP instance +// +#define WIN_NT_INSTANCE_SIGNATURE SIGNATURE_32 ('N', 'T', 'I', 'S') + +typedef struct { + UINT32 Signature; + + // + // Array of the recycled transmit buffer address. + // + UINT64 *RecycledTxBuf; + + // + // Current number of recycled buffer pointers in RecycledTxBuf. + // + UINT32 RecycledTxBufCount; + + // + // The maximum number of recycled buffer pointers in RecycledTxBuf. + // + UINT32 MaxRecycledTxBuf; + EFI_SIMPLE_NETWORK_MODE Mode; + NT_NET_INTERFACE_INFO InterfaceInfo; +} WIN_NT_INSTANCE_DATA; + +// +// Instance data for each SNP private instance +// +#define WIN_NT_SIMPLE_NETWORK_PRIVATE_SIGNATURE SIGNATURE_32 ('N', 'T', 's', 'n') + +typedef struct { + UINTN Signature; + EMU_IO_THUNK_PROTOCOL *Thunk; + EMU_SNP_PROTOCOL EmuSnp; + EFI_SIMPLE_NETWORK_MODE *Mode; + HMODULE NetworkLibraryHandle; + NT_NET_UTILITY_TABLE NtNetUtilityTable; + WIN_NT_INSTANCE_DATA Instance; +} WIN_NT_SNP_PRIVATE; + +#define WIN_NT_SNP_PRIVATE_DATA_FROM_THIS(a) \ + CR(a, WIN_NT_SNP_PRIVATE, EmuSnp, WIN_NT_SIMPLE_NETWORK_PRIVATE_SIGNATURE) + + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpCreateMapping ( + IN EMU_SNP_PROTOCOL *This, + IN EFI_SIMPLE_NETWORK_MODE *Mode + ) +{ + WIN_NT_SNP_PRIVATE *Private; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + Private->Mode = Mode; + + // + // Set the broadcast address. + // + CopyMem (&Mode->BroadcastAddress, &Private->Instance.Mode.BroadcastAddress, sizeof (EFI_MAC_ADDRESS)); + // + // Set the MAC address. + // + CopyMem (&Mode->CurrentAddress, &Private->Instance.Mode.CurrentAddress, sizeof (EFI_MAC_ADDRESS)); + CopyMem (&Mode->PermanentAddress, &Private->Instance.Mode.PermanentAddress, sizeof (EFI_MAC_ADDRESS)); + + return EFI_SUCCESS; +} + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpStart ( + IN EMU_SNP_PROTOCOL *This + ) +{ + WIN_NT_SNP_PRIVATE *Private; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + switch (Private->Mode->State) { + case EfiSimpleNetworkStopped: + break; + + case EfiSimpleNetworkStarted: + case EfiSimpleNetworkInitialized: + return EFI_ALREADY_STARTED; + break; + + default: + return EFI_DEVICE_ERROR; + break; + } + + Private->Mode->State = EfiSimpleNetworkStarted; + + return EFI_SUCCESS; +} + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpStop ( + IN EMU_SNP_PROTOCOL *This + ) +{ + WIN_NT_SNP_PRIVATE *Private; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + switch ( Private->Mode->State ) { + case EfiSimpleNetworkStarted: + break; + + case EfiSimpleNetworkStopped: + return EFI_NOT_STARTED; + break; + + default: + return EFI_DEVICE_ERROR; + break; + } + + Private->Mode->State = EfiSimpleNetworkStopped; + + return EFI_SUCCESS; +} + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpInitialize ( + IN EMU_SNP_PROTOCOL *This, + IN UINTN ExtraRxBufferSize OPTIONAL, + IN UINTN ExtraTxBufferSize OPTIONAL + ) +{ + WIN_NT_SNP_PRIVATE *Private; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + switch ( Private->Mode->State ) { + case EfiSimpleNetworkStarted: + break; + + case EfiSimpleNetworkStopped: + return EFI_NOT_STARTED; + break; + + default: + return EFI_DEVICE_ERROR; + break; + } + + Private->Mode->MCastFilterCount = 0; + Private->Mode->ReceiveFilterSetting = 0; + ZeroMem (Private->Mode->MCastFilter, sizeof (Private->Mode->MCastFilter)); + + Private->Mode->State = EfiSimpleNetworkInitialized; + + return EFI_SUCCESS; +} + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpReset ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +{ + WIN_NT_SNP_PRIVATE *Private; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + switch ( Private->Mode->State ) { + case EfiSimpleNetworkInitialized: + break; + + case EfiSimpleNetworkStopped: + return EFI_NOT_STARTED; + break; + + default: + return EFI_DEVICE_ERROR; + break; + } + + return EFI_SUCCESS; +} + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpShutdown ( + IN EMU_SNP_PROTOCOL *This + ) +{ + WIN_NT_SNP_PRIVATE *Private; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + switch ( Private->Mode->State ) { + case EfiSimpleNetworkInitialized: + break; + + case EfiSimpleNetworkStopped: + return EFI_NOT_STARTED; + break; + + default: + return EFI_DEVICE_ERROR; + break; + } + + Private->Mode->State = EfiSimpleNetworkStarted; + + Private->Mode->ReceiveFilterSetting = 0; + Private->Mode->MCastFilterCount = 0; + ZeroMem (Private->Mode->MCastFilter, sizeof (Private->Mode->MCastFilter)); + + return EFI_SUCCESS; +} + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpReceiveFilters ( + IN EMU_SNP_PROTOCOL *This, + IN UINT32 Enable, + IN UINT32 Disable, + IN BOOLEAN ResetMCastFilter, + IN UINTN MCastFilterCnt OPTIONAL, + IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL + ) +{ + WIN_NT_SNP_PRIVATE *Private; + INT32 ReturnValue; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + ReturnValue = Private->NtNetUtilityTable.SetReceiveFilter ( + Private->Instance.InterfaceInfo.InterfaceIndex, + Enable, + (UINT32)MCastFilterCnt, + MCastFilter + ); + + if (ReturnValue <= 0) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpStationAddress ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN Reset, + IN EFI_MAC_ADDRESS *New OPTIONAL + ) +{ + WIN_NT_SNP_PRIVATE *Private; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpStatistics ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN Reset, + IN OUT UINTN *StatisticsSize OPTIONAL, + OUT EFI_NETWORK_STATISTICS *StatisticsTable OPTIONAL + ) +{ + WIN_NT_SNP_PRIVATE *Private; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpMCastIpToMac ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN IPv6, + IN EFI_IP_ADDRESS *IP, + OUT EFI_MAC_ADDRESS *MAC + ) +{ + WIN_NT_SNP_PRIVATE *Private; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpNvData ( + IN EMU_SNP_PROTOCOL *This, + IN BOOLEAN ReadWrite, + IN UINTN Offset, + IN UINTN BufferSize, + IN OUT VOID *Buffer + ) +{ + WIN_NT_SNP_PRIVATE *Private; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + return EFI_UNSUPPORTED; +} + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpGetStatus ( + IN EMU_SNP_PROTOCOL *This, + OUT UINT32 *InterruptStatus OPTIONAL, + OUT VOID **TxBuf OPTIONAL + ) +{ + WIN_NT_SNP_PRIVATE *Private; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + if (TxBuf != NULL) { + if (Private->Instance.RecycledTxBufCount != 0) { + Private->Instance.RecycledTxBufCount --; + *((UINT8 **) TxBuf) = (UINT8 *) (UINTN)Private->Instance.RecycledTxBuf[Private->Instance.RecycledTxBufCount]; + } else { + *((UINT8 **) TxBuf) = NULL; + } + } + + if (InterruptStatus != NULL) { + *InterruptStatus = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT; + } + + return EFI_SUCCESS; +} + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpTransmit ( + 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 + ) +{ + WIN_NT_SNP_PRIVATE *Private; + INT32 ReturnValue; + UINT64 *Tmp; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + if ((HeaderSize != 0) && (SrcAddr == NULL)) { + SrcAddr = &Private->Instance.Mode.CurrentAddress; + } + + ReturnValue = Private->NtNetUtilityTable.Transmit ( + Private->Instance.InterfaceInfo.InterfaceIndex, + (UINT32)HeaderSize, + (UINT32)BufferSize, + Buffer, + SrcAddr, + DestAddr, + Protocol + ); + + if (ReturnValue < 0) { + return EFI_DEVICE_ERROR; + } else { + if ((Private->Instance.MaxRecycledTxBuf + SNP_TX_BUFFER_INCREASEMENT) >= SNP_MAX_TX_BUFFER_NUM) { + return EFI_NOT_READY; + } + + if (Private->Instance.RecycledTxBufCount < Private->Instance.MaxRecycledTxBuf) { + Private->Instance.RecycledTxBuf[Private->Instance.RecycledTxBufCount] = (UINT64) Buffer; + Private->Instance.RecycledTxBufCount ++; + } else { + Tmp = malloc (sizeof (UINT64) * (Private->Instance.MaxRecycledTxBuf + SNP_TX_BUFFER_INCREASEMENT)); + if (Tmp == NULL) { + return EFI_DEVICE_ERROR; + } + CopyMem (Tmp, Private->Instance.RecycledTxBuf, sizeof (UINT64) * Private->Instance.RecycledTxBufCount); + free (Private->Instance.RecycledTxBuf); + Private->Instance.RecycledTxBuf = Tmp; + Private->Instance.MaxRecycledTxBuf += SNP_TX_BUFFER_INCREASEMENT; + } + } + + return EFI_SUCCESS; +} + +/** + 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. + +**/ +EFI_STATUS +WinNtSnpReceive ( + 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 + ) +{ + WIN_NT_SNP_PRIVATE *Private; + INT32 ReturnValue; + UINTN BufSize; + + Private = WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This); + + BufSize = *BufferSize; + + ASSERT (Private->NtNetUtilityTable.Receive != NULL); + + ReturnValue = Private->NtNetUtilityTable.Receive ( + Private->Instance.InterfaceInfo.InterfaceIndex, + BufferSize, + Buffer + ); + + if (ReturnValue < 0) { + if (ReturnValue == -100) { + return EFI_BUFFER_TOO_SMALL; + } + + return EFI_DEVICE_ERROR; + } else if (ReturnValue == 0) { + return EFI_NOT_READY; + } + + if (HeaderSize != NULL) { + *HeaderSize = 14; + } + + if (SrcAddr != NULL) { + ZeroMem (SrcAddr, sizeof (EFI_MAC_ADDRESS)); + CopyMem (SrcAddr, ((UINT8 *) Buffer) + 6, 6); + } + + if (DestAddr != NULL) { + ZeroMem (DestAddr, sizeof (EFI_MAC_ADDRESS)); + CopyMem (DestAddr, ((UINT8 *) Buffer), 6); + } + + if (Protocol != NULL) { + *Protocol = NTOHS (*((UINT16 *) (((UINT8 *) Buffer) + 12))); + } + + return (*BufferSize <= BufSize) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL; +} + +/** + Initialize the snpnt32 driver instance. + + @param Instance Pointer to the instance context data. + @param NetInfo Pointer to the interface info. + + @retval EFI_SUCCESS The driver instance is initialized. + @retval other Initialization errors. + +**/ +EFI_STATUS +WinNtInitializeInstanceData ( + IN OUT WIN_NT_INSTANCE_DATA *Instance, + IN NT_NET_INTERFACE_INFO *NetInfo + ) +{ + if (Instance == NULL || NetInfo == NULL) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (Instance, sizeof (WIN_NT_INSTANCE_DATA)); + + Instance->Signature = WIN_NT_INSTANCE_SIGNATURE; + Instance->RecycledTxBufCount = 0; + Instance->MaxRecycledTxBuf = 32; + Instance->Mode.State = EfiSimpleNetworkInitialized; + Instance->Mode.HwAddressSize = NET_ETHER_ADDR_LEN; + Instance->Mode.MediaHeaderSize = NET_ETHER_HEADER_SIZE; + Instance->Mode.MaxPacketSize = 1500; + Instance->Mode.MaxMCastFilterCount = MAX_MCAST_FILTER_CNT; + Instance->Mode.IfType = NET_IFTYPE_ETHERNET; + Instance->Mode.MediaPresentSupported = TRUE; + Instance->Mode.MediaPresent = TRUE; + + // + // Allocate the RecycledTxBuf. + // + Instance->RecycledTxBuf = malloc (sizeof (UINT64) * Instance->MaxRecycledTxBuf); + if (Instance->RecycledTxBuf == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Set the interface information. + // + CopyMem (&Instance->InterfaceInfo, NetInfo, sizeof (Instance->InterfaceInfo)); + + + // + // Set broadcast address + // + SetMem (&Instance->Mode.BroadcastAddress, sizeof (EFI_MAC_ADDRESS), 0xFF); + + // + // Copy Current/PermanentAddress MAC address + // + CopyMem (&Instance->Mode.CurrentAddress, &Instance->InterfaceInfo.MacAddr, sizeof(Instance->Mode.CurrentAddress)); + CopyMem (&Instance->Mode.PermanentAddress, &Instance->InterfaceInfo.MacAddr, sizeof(Instance->Mode.PermanentAddress)); + + // + // Since the fake SNP is based on a real NIC, to avoid conflict with the host + // NIC network stack, we use a different MAC address. + // So just change the last byte of the MAC address for the real NIC. + // + Instance->Mode.CurrentAddress.Addr[NET_ETHER_ADDR_LEN - 1]++; + + return EFI_SUCCESS; +} + +/** + Initialize the net utility data. + + @param This Pointer to the private data. + @param ActiveInstance The active network interface. + + @retval EFI_SUCCESS The global data is initialized. + @retval EFI_NOT_FOUND The required DLL is not found. + @retval EFI_DEVICE_ERROR Error initialize network utility library. + @retval other Other errors. + +**/ +EFI_STATUS +WintNtInitializeNetUtilityData ( + IN OUT WIN_NT_SNP_PRIVATE *Private, + IN UINT8 ActiveInstance + ) +{ + EFI_STATUS Status; + CHAR16 *DllFileNameU; + INT32 ReturnValue; + BOOLEAN NetUtilityLibInitDone; + NT_NET_INTERFACE_INFO NetInterfaceInfoBuffer[MAX_INTERFACE_INFO_NUMBER]; + UINT32 InterfaceCount; + UINT8 ActiveInterfaceIndex; + + if (Private == NULL) { + return EFI_INVALID_PARAMETER; + } + + NetUtilityLibInitDone = FALSE; + InterfaceCount = MAX_INTERFACE_INFO_NUMBER; + DllFileNameU = NETWORK_LIBRARY_NAME_U; + + // + // Load network utility library + // + Private->NetworkLibraryHandle = LoadLibraryEx (DllFileNameU, NULL, 0); + if (NULL == Private->NetworkLibraryHandle) { + return EFI_NOT_FOUND; + } + + Private->NtNetUtilityTable.Initialize = (NT_NET_INITIALIZE) GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_INITIALIZE); + if (NULL == Private->NtNetUtilityTable.Initialize) { + Status = EFI_NOT_FOUND; + goto ErrorReturn; + } + + Private->NtNetUtilityTable.Finalize = (NT_NET_FINALIZE) GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_FINALIZE); + if (NULL == Private->NtNetUtilityTable.Finalize) { + Status = EFI_NOT_FOUND; + goto ErrorReturn; + } + + Private->NtNetUtilityTable.SetReceiveFilter = (NT_NET_SET_RECEIVE_FILTER) GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_SET_RCV_FILTER); + if (NULL == Private->NtNetUtilityTable.SetReceiveFilter) { + Status = EFI_NOT_FOUND; + goto ErrorReturn; + } + + Private->NtNetUtilityTable.Receive = (NT_NET_RECEIVE) GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_RECEIVE); + if (NULL == Private->NtNetUtilityTable.Receive) { + Status = EFI_NOT_FOUND; + goto ErrorReturn; + } + + Private->NtNetUtilityTable.Transmit = (NT_NET_TRANSMIT) GetProcAddress (Private->NetworkLibraryHandle, NETWORK_LIBRARY_TRANSMIT); + if (NULL == Private->NtNetUtilityTable.Transmit) { + Status = EFI_NOT_FOUND; + goto ErrorReturn; + } + + // + // Initialize the network utility library + // And enumerate the interfaces in emulator host + // + ReturnValue = Private->NtNetUtilityTable.Initialize (&InterfaceCount, &NetInterfaceInfoBuffer[0]); + if (ReturnValue <= 0) { + Status = EFI_DEVICE_ERROR; + goto ErrorReturn; + } + + NetUtilityLibInitDone = TRUE; + + if (InterfaceCount == 0) { + Status = EFI_NOT_FOUND; + goto ErrorReturn; + } + + DEBUG ((DEBUG_INFO, "%a, total %d interface(s) found\n", __FUNCTION__, InterfaceCount)); + // + // Active interface index is set to first interface if given instance does + // not exist. + // + ActiveInterfaceIndex = (ActiveInstance >= InterfaceCount ? DEFAULT_SELECTED_NIC_INDEX : ActiveInstance); + + // + // Initialize instance + // + Status = WinNtInitializeInstanceData (&Private->Instance, &NetInterfaceInfoBuffer[ActiveInterfaceIndex]); + if (EFI_ERROR (Status)) { + goto ErrorReturn; + } + + return EFI_SUCCESS; + +ErrorReturn: + + if (Private->Instance.RecycledTxBuf != NULL) { + free (Private->Instance.RecycledTxBuf); + } + + if (NetUtilityLibInitDone) { + if (Private->NtNetUtilityTable.Finalize != NULL) { + Private->NtNetUtilityTable.Finalize (); + Private->NtNetUtilityTable.Finalize = NULL; + } + } + + return Status; +} + +/** + Release the net utility data. + + @param This Pointer to the private data. + + @retval EFI_SUCCESS The global data is released. + @retval other Other errors. + +**/ +EFI_STATUS +WintNtReleaseNetUtilityData ( + IN OUT WIN_NT_SNP_PRIVATE *Private + ) +{ + if (Private == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Private->Instance.RecycledTxBuf != NULL) { + free (Private->Instance.RecycledTxBuf); + } + + if (Private->NtNetUtilityTable.Finalize != NULL) { + Private->NtNetUtilityTable.Finalize (); + } + + FreeLibrary (Private->NetworkLibraryHandle); + + return EFI_SUCCESS; +} + +EMU_SNP_PROTOCOL mWinNtSnpProtocol = { + WinNtSnpCreateMapping, + WinNtSnpStart, + WinNtSnpStop, + WinNtSnpInitialize, + WinNtSnpReset, + WinNtSnpShutdown, + WinNtSnpReceiveFilters, + WinNtSnpStationAddress, + WinNtSnpStatistics, + WinNtSnpMCastIpToMac, + WinNtSnpNvData, + WinNtSnpGetStatus, + WinNtSnpTransmit, + WinNtSnpReceive +}; + +/** + Open SNP thunk protocol. + + @param This Pointer to the thunk protocol instance. + + @retval EFI_SUCCESS SNP thunk protocol is opened successfully. + @retval EFI_UNSUPPORTED This is not SNP thunk protocol. + @retval EFI_OUT_OF_RESOURCES Not enough memory. + @retval other Other errors. + +**/ +EFI_STATUS +WinNtSnpThunkOpen ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + WIN_NT_SNP_PRIVATE *Private; + UINT8 HostInterfaceIndex; + + HostInterfaceIndex = 0; + + if (This->Private != NULL) { + return EFI_ALREADY_STARTED; + } + + if (!CompareGuid (This->Protocol, &gEmuSnpProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + Private = malloc (sizeof (WIN_NT_SNP_PRIVATE)); + if (Private == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Private->Signature = WIN_NT_SIMPLE_NETWORK_PRIVATE_SIGNATURE; + Private->Thunk = This; + CopyMem (&Private->EmuSnp, &mWinNtSnpProtocol, sizeof (mWinNtSnpProtocol)); + + This->Interface = &Private->EmuSnp; + This->Private = Private; + + if (This->ConfigString != NULL && This->ConfigString[0] != '\0') { + HostInterfaceIndex = (UINT8)StrDecimalToUintn (This->ConfigString); + } + + return WintNtInitializeNetUtilityData (Private, HostInterfaceIndex); +} + +/** + Close SNP thunk protocol. + + @param This Pointer to the thunk protocol instance. + + @retval EFI_SUCCESS SNP thunk protocol is closed successfully. + @retval EFI_UNSUPPORTED This is not SNP thunk protocol. + @retval other Other errors. + +**/ +EFI_STATUS +WinNtSnpThunkClose ( + IN EMU_IO_THUNK_PROTOCOL *This + ) +{ + WIN_NT_SNP_PRIVATE *Private; + + if (!CompareGuid (This->Protocol, &gEmuSnpProtocolGuid)) { + return EFI_UNSUPPORTED; + } + + Private = This->Private; + WintNtReleaseNetUtilityData (Private); + free (Private); + + return EFI_SUCCESS; +} + +EMU_IO_THUNK_PROTOCOL mWinNtSnpThunkIo = { + &gEmuSnpProtocolGuid, + NULL, + NULL, + 0, + WinNtSnpThunkOpen, + WinNtSnpThunkClose, + NULL +}; diff --git a/CdeEmuPkg/EmulatorPkg/Win/Host/WinThunk.c b/CdeEmuPkg/EmulatorPkg/Win/Host/WinThunk.c new file mode 100644 index 00000000000..da6d8998217 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/Host/WinThunk.c @@ -0,0 +1,580 @@ +/**@file + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +Module Name: + + WinNtThunk.c + +Abstract: + + Since the SEC is the only windows program in our emulation we + must use a Tiano mechanism to export Win32 APIs to other modules. + This is the role of the EFI_WIN_NT_THUNK_PROTOCOL. + + The mWinNtThunkTable exists so that a change to EFI_WIN_NT_THUNK_PROTOCOL + will cause an error in initializing the array if all the member functions + are not added. It looks like adding a element to end and not initializing + it may cause the table to be initaliized with the members at the end being + set to zero. This is bad as jumping to zero will case the NT32 to crash. + + All the member functions in mWinNtThunkTable are Win32 + API calls, so please reference Microsoft documentation. + + + gWinNt is a a public exported global that contains the initialized + data. + +**/ + +#include "WinHost.h" + +UINTN +SecWriteStdErr ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + BOOL Success; + DWORD CharCount; + + CharCount = (DWORD)NumberOfBytes; + Success = WriteFile ( + GetStdHandle (STD_ERROR_HANDLE), + Buffer, + CharCount, + &CharCount, + NULL + ); + + return Success ? CharCount : 0; +} + + +EFI_STATUS +SecConfigStdIn ( + VOID + ) +{ + BOOL Success; + DWORD Mode; + + Success = GetConsoleMode (GetStdHandle (STD_INPUT_HANDLE), &Mode); + if (Success) { + // + // Disable buffer (line input), echo, mouse, window + // + Mode &= ~(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT); + +#if defined(NTDDI_VERSION) && defined (NTDDI_WIN10_TH2) && (NTDDI_VERSION > NTDDI_WIN10_TH2) + // + // Enable virtual terminal input for Win10 above TH2 + // + Mode |= ENABLE_VIRTUAL_TERMINAL_INPUT; +#endif + + Success = SetConsoleMode (GetStdHandle (STD_INPUT_HANDLE), Mode); + } + +#if defined(NTDDI_VERSION) && defined (NTDDI_WIN10_TH2) && (NTDDI_VERSION > NTDDI_WIN10_TH2) + // + // Enable terminal mode for Win10 above TH2 + // + if (Success) { + Success = GetConsoleMode (GetStdHandle (STD_OUTPUT_HANDLE), &Mode); + if (Success) { + Success = SetConsoleMode ( + GetStdHandle (STD_OUTPUT_HANDLE), + Mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN + ); + } + } +#endif + return Success ? EFI_SUCCESS : EFI_DEVICE_ERROR; +} + +UINTN +SecWriteStdOut ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + BOOL Success; + DWORD CharCount; + + CharCount = (DWORD)NumberOfBytes; + Success = WriteFile ( + GetStdHandle (STD_OUTPUT_HANDLE), + Buffer, + CharCount, + &CharCount, + NULL + ); + + return Success ? CharCount : 0; +} + +BOOLEAN +SecPollStdIn ( + VOID + ) +{ + BOOL Success; + INPUT_RECORD Record; + DWORD RecordNum; + + do { + Success = GetNumberOfConsoleInputEvents (GetStdHandle (STD_INPUT_HANDLE), &RecordNum); + if (!Success || (RecordNum == 0)) { + break; + } + Success = PeekConsoleInput ( + GetStdHandle (STD_INPUT_HANDLE), + &Record, + 1, + &RecordNum + ); + if (Success && (RecordNum == 1)) { + if (Record.EventType == KEY_EVENT && Record.Event.KeyEvent.bKeyDown) { + return TRUE; + } else { + // + // Consume the non-key event. + // + Success = ReadConsoleInput ( + GetStdHandle (STD_INPUT_HANDLE), + &Record, + 1, + &RecordNum + ); + } + } + } while (Success); + + return FALSE; +} + +UINTN +SecReadStdIn ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + BOOL Success; + INPUT_RECORD Record; + DWORD RecordNum; + UINTN BytesReturn; + + if (!SecPollStdIn ()) { + return 0; + } + Success = ReadConsoleInput ( + GetStdHandle (STD_INPUT_HANDLE), + &Record, + 1, + &RecordNum + ); + ASSERT (Success && (RecordNum == 1) && (Record.EventType == KEY_EVENT) && (Record.Event.KeyEvent.bKeyDown)); + NumberOfBytes = MIN (Record.Event.KeyEvent.wRepeatCount, NumberOfBytes); + BytesReturn = NumberOfBytes; + while (NumberOfBytes-- != 0) { + Buffer[NumberOfBytes] = Record.Event.KeyEvent.uChar.AsciiChar; + } + return BytesReturn; +} + + +VOID * +SecAlloc ( + IN UINTN Size + ) +{ + return malloc ((size_t)Size); +} + +BOOLEAN +SecFree ( + IN VOID *Ptr + ) +{ + if (EfiSystemMemoryRange (Ptr)) { + // If an address range is in the EFI memory map it was alloced via EFI. + // So don't free those ranges and let the caller know. + return FALSE; + } + + free (Ptr); + return TRUE; +} + + + +// +// Define a global that we can use to shut down the NT timer thread when +// the timer is canceled. +// +BOOLEAN mCancelTimerThread = FALSE; + +// +// The notification function to call on every timer interrupt +// +EMU_SET_TIMER_CALLBACK *mTimerNotifyFunction = NULL; + +// +// The thread handle for this driver +// +HANDLE mNtMainThreadHandle; + +// +// The timer value from the last timer interrupt +// +UINT32 mNtLastTick; + +// +// Critical section used to update varibles shared between the main thread and +// the timer interrupt thread. +// +CRITICAL_SECTION mNtCriticalSection; + +// +// Worker Functions +// +UINT mMMTimerThreadID = 0; + +volatile BOOLEAN mInterruptEnabled = FALSE; + +VOID +CALLBACK +MMTimerThread ( + UINT wTimerID, + UINT msg, + DWORD dwUser, + DWORD dw1, + DWORD dw2 +) +{ + UINT32 CurrentTick; + UINT32 Delta; + + if (!mCancelTimerThread) { + + // + // Suspend the main thread until we are done. + // Enter the critical section before suspending + // and leave the critical section after resuming + // to avoid deadlock between main and timer thread. + // + EnterCriticalSection (&mNtCriticalSection); + SuspendThread (mNtMainThreadHandle); + + // + // If the timer thread is being canceled, then bail immediately. + // We check again here because there's a small window of time from when + // this thread was kicked off and when we suspended the main thread above. + // + if (mCancelTimerThread) { + ResumeThread (mNtMainThreadHandle); + LeaveCriticalSection (&mNtCriticalSection); + timeKillEvent (wTimerID); + mMMTimerThreadID = 0; + return; + } + + while (!mInterruptEnabled) { + // + // Resume the main thread + // + ResumeThread (mNtMainThreadHandle); + LeaveCriticalSection (&mNtCriticalSection); + + // + // Wait for interrupts to be enabled. + // + while (!mInterruptEnabled) { + Sleep (1); + } + + // + // Suspend the main thread until we are done + // + EnterCriticalSection (&mNtCriticalSection); + SuspendThread (mNtMainThreadHandle); + } + + // + // Get the current system tick + // + CurrentTick = GetTickCount (); + Delta = CurrentTick - mNtLastTick; + mNtLastTick = CurrentTick; + + // + // If delay was more then 1 second, ignore it (probably debugging case) + // + if (Delta < 1000) { + + // + // Only invoke the callback function if a Non-NULL handler has been + // registered. Assume all other handlers are legal. + // + if (mTimerNotifyFunction != NULL) { + mTimerNotifyFunction (Delta); + } + } + + // + // Resume the main thread + // + ResumeThread (mNtMainThreadHandle); + LeaveCriticalSection (&mNtCriticalSection); + } else { + timeKillEvent (wTimerID); + mMMTimerThreadID = 0; + } + +} + +VOID +SecSetTimer ( + IN UINT64 TimerPeriod, + IN EMU_SET_TIMER_CALLBACK Callback +) +{ + // +// If TimerPeriod is 0, then the timer thread should be canceled +// + if (TimerPeriod == 0) { + // + // Cancel the timer thread + // + EnterCriticalSection (&mNtCriticalSection); + + mCancelTimerThread = TRUE; + + LeaveCriticalSection (&mNtCriticalSection); + + // + // Wait for the timer thread to exit + // + + if (mMMTimerThreadID != 0) { + timeKillEvent (mMMTimerThreadID); + mMMTimerThreadID = 0; + } + } else { + // + // If the TimerPeriod is valid, then create and/or adjust the period of the timer thread + // + EnterCriticalSection (&mNtCriticalSection); + + mCancelTimerThread = FALSE; + + LeaveCriticalSection (&mNtCriticalSection); + + // + // Get the starting tick location if we are just starting the timer thread + // + mNtLastTick = GetTickCount (); + + if (mMMTimerThreadID) { + timeKillEvent (mMMTimerThreadID); + } + + SetThreadPriority ( + GetCurrentThread (), + THREAD_PRIORITY_HIGHEST + ); + + mMMTimerThreadID = timeSetEvent ( + (UINT)TimerPeriod, + 0, + MMTimerThread, + (DWORD_PTR)NULL, + TIME_PERIODIC | TIME_KILL_SYNCHRONOUS | TIME_CALLBACK_FUNCTION + ); + } + mTimerNotifyFunction = Callback; +} + +VOID +SecInitializeThunk ( + VOID +) +{ + InitializeCriticalSection (&mNtCriticalSection); + + DuplicateHandle ( + GetCurrentProcess (), + GetCurrentThread (), + GetCurrentProcess (), + &mNtMainThreadHandle, + 0, + FALSE, + DUPLICATE_SAME_ACCESS + ); +} + +VOID +SecEnableInterrupt ( + VOID + ) +{ + mInterruptEnabled = TRUE; +} + + +VOID +SecDisableInterrupt ( + VOID + ) +{ + mInterruptEnabled = FALSE; +} + + +UINT64 +SecQueryPerformanceFrequency ( + VOID + ) +{ + // Hard code to nanoseconds + return 1000000000ULL; +} + +UINT64 +SecQueryPerformanceCounter ( + VOID + ) +{ + return 0; +} + + + +VOID +SecSleep ( + IN UINT64 Nanoseconds + ) +{ + Sleep ((DWORD)DivU64x32 (Nanoseconds, 1000000)); +} + + +VOID +SecCpuSleep ( + VOID + ) +{ + Sleep (1); +} + + +VOID +SecExit ( + UINTN Status + ) +{ + exit ((int)Status); +} + + +VOID +SecGetTime ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ) +{ + SYSTEMTIME SystemTime; + TIME_ZONE_INFORMATION TimeZone; + + GetLocalTime (&SystemTime); + GetTimeZoneInformation (&TimeZone); + + Time->Year = (UINT16)SystemTime.wYear; + Time->Month = (UINT8)SystemTime.wMonth; + Time->Day = (UINT8)SystemTime.wDay; + Time->Hour = (UINT8)SystemTime.wHour; + Time->Minute = (UINT8)SystemTime.wMinute; + Time->Second = (UINT8)SystemTime.wSecond; + Time->Nanosecond = (UINT32)(SystemTime.wMilliseconds * 1000000); + Time->TimeZone = (INT16)TimeZone.Bias; + + if (Capabilities != NULL) { + Capabilities->Resolution = 1; + Capabilities->Accuracy = 50000000; + Capabilities->SetsToZero = FALSE; + } + + Time->Daylight = 0; + if (TimeZone.StandardDate.wMonth) { + Time->Daylight = (UINT8)TimeZone.StandardDate.wMonth; + } +} + +EFI_STATUS +SecSetTime ( + IN EFI_TIME *Time + ) +{ + TIME_ZONE_INFORMATION TimeZone; + SYSTEMTIME SystemTime; + BOOL Flag; + + // + // Set Daylight savings time information and Time Zone + // + GetTimeZoneInformation (&TimeZone); + TimeZone.StandardDate.wMonth = Time->Daylight; + TimeZone.Bias = Time->TimeZone; + Flag = SetTimeZoneInformation (&TimeZone); + if (!Flag) { + return EFI_DEVICE_ERROR; + } + + SystemTime.wYear = Time->Year; + SystemTime.wMonth = Time->Month; + SystemTime.wDay = Time->Day; + SystemTime.wHour = Time->Hour; + SystemTime.wMinute = Time->Minute; + SystemTime.wSecond = Time->Second; + SystemTime.wMilliseconds = (INT16)(Time->Nanosecond / 1000000); + + Flag = SetLocalTime (&SystemTime); + + if (!Flag) { + return EFI_DEVICE_ERROR; + } else { + return EFI_SUCCESS; + } +} + +EMU_THUNK_PROTOCOL gEmuThunkProtocol = { + SecWriteStdErr, + SecConfigStdIn, + SecWriteStdOut, + SecReadStdIn, + SecPollStdIn, + SecAlloc, + NULL, + SecFree, + SecPeCoffGetEntryPoint, + PeCoffLoaderRelocateImageExtraAction, + PeCoffLoaderUnloadImageExtraAction, + SecEnableInterrupt, + SecDisableInterrupt, + SecQueryPerformanceFrequency, + SecQueryPerformanceCounter, + SecSleep, + SecCpuSleep, + SecExit, + SecGetTime, + SecSetTime, + SecSetTimer, + GetNextThunkProtocol +}; + + +#pragma warning(default : 4996) +#pragma warning(default : 4232) + diff --git a/CdeEmuPkg/EmulatorPkg/Win/VS2017/BuildVS.bat b/CdeEmuPkg/EmulatorPkg/Win/VS2017/BuildVS.bat new file mode 100644 index 00000000000..aaee3a5734d --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/VS2017/BuildVS.bat @@ -0,0 +1,3 @@ +cd ../../../ +@call edksetup.bat +build -p EmulatorPkg\EmulatorPkg.dsc -t VS2017 %* diff --git a/CdeEmuPkg/EmulatorPkg/Win/VS2017/Win.sln b/CdeEmuPkg/EmulatorPkg/Win/VS2017/Win.sln new file mode 100644 index 00000000000..8a2e259ebed --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/VS2017/Win.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2003 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Win", "Win.vcxproj", "{B4E1783F-FD72-4214-B0F7-69271BAD5DDF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B4E1783F-FD72-4214-B0F7-69271BAD5DDF}.Debug|x64.ActiveCfg = Debug|x64 + {B4E1783F-FD72-4214-B0F7-69271BAD5DDF}.Debug|x64.Build.0 = Debug|x64 + {B4E1783F-FD72-4214-B0F7-69271BAD5DDF}.Debug|x86.ActiveCfg = Debug|Win32 + {B4E1783F-FD72-4214-B0F7-69271BAD5DDF}.Debug|x86.Build.0 = Debug|Win32 + {B4E1783F-FD72-4214-B0F7-69271BAD5DDF}.Release|x64.ActiveCfg = Release|x64 + {B4E1783F-FD72-4214-B0F7-69271BAD5DDF}.Release|x64.Build.0 = Release|x64 + {B4E1783F-FD72-4214-B0F7-69271BAD5DDF}.Release|x86.ActiveCfg = Release|Win32 + {B4E1783F-FD72-4214-B0F7-69271BAD5DDF}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection +EndGlobal diff --git a/CdeEmuPkg/EmulatorPkg/Win/VS2017/Win.vcxproj b/CdeEmuPkg/EmulatorPkg/Win/VS2017/Win.vcxproj new file mode 100644 index 00000000000..3210c24751e --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/VS2017/Win.vcxproj @@ -0,0 +1,120 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {B4E1783F-FD72-4214-B0F7-69271BAD5DDF} + MakeFileProj + 8.1 + + + + Makefile + true + v141 + + + Makefile + false + v141 + + + Makefile + true + v141 + + + Makefile + true + v141 + + + + + + + + + + + + + + + + + + + + + BuildVS.bat -a IA32 + BuildVS.bat -a IA32 all + BuildVS.bat -a IA32 clean + ..\..\..\Build\EmulatorIA32\DEBUG_VS2017\ + ..\..\..\Build\EmulatorIA32\DEBUG_VS2017\ + ..\..\..\MdePkg\Include;..\..\..\MdePkg\Include\Ia32;..\..\..\MdeModulePkg\Include;..\..\..\EmulatorPkg\Include;$(IncludePath) + + + BuildVS.bat -a IA32 -b RELEASE + + + BuildVS.bat -a IA32 -b RELEASE all + BuildVS.bat -a IA32 -b RELEASE clean + ..\..\..\Build\EmulatorIA32\DEBUG_VS2017\ + ..\..\..\Build\EmulatorIA32\DEBUG_VS2017\ + ..\..\..\MdePkg\Include;..\..\..\MdePkg\Include\Ia32;..\..\..\MdeModulePkg\Include;..\..\..\EmulatorPkg\Include;$(IncludePath) + + + BuildVS.bat -a X64 + BuildVS.bat -a X64 all + BuildVS.bat -a X64 clean + ..\..\..\Build\EmulatorX64\DEBUG_VS2017\ + ..\..\..\Build\EmulatorX64\DEBUG_VS2017\ + ..\..\..\MdePkg\Include;..\..\..\MdePkg\Include\X64;..\..\..\MdeModulePkg\Include;..\..\..\EmulatorPkg\Include;$(IncludePath) + + + BuildVS.bat -a X64 -b RELEASE + BuildVS.bat -a X64 -b RELEASE all + BuildVS.bat -a X64 -b RELEASE clean + ..\..\Build\EmulatorX64\DEBUG_VS2017\ + ..\..\Build\EmulatorX64\DEBUG_VS2017\ + ..\..\..\MdePkg\Include;..\..\..\MdePkg\Include\X64;..\..\..\MdeModulePkg\Include;..\..\..\EmulatorPkg\Include;$(IncludePath) + + + + + + + + + + + + + + + + + + + + + + diff --git a/CdeEmuPkg/EmulatorPkg/Win/VS2017/Win.vcxproj.filters b/CdeEmuPkg/EmulatorPkg/Win/VS2017/Win.vcxproj.filters new file mode 100644 index 00000000000..6baadbcd727 --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/VS2017/Win.vcxproj.filters @@ -0,0 +1,50 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + + \ No newline at end of file diff --git a/CdeEmuPkg/EmulatorPkg/Win/VS2017/Win.vcxproj.user b/CdeEmuPkg/EmulatorPkg/Win/VS2017/Win.vcxproj.user new file mode 100644 index 00000000000..101a181ee0f --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/Win/VS2017/Win.vcxproj.user @@ -0,0 +1,13 @@ + + + + WinHost.exe + WindowsLocalDebugger + $(ProjectDir)..\..\..\Build\EmulatorIA32\DEBUG_VS2017\IA32\ + + + WinHost.exe + $(ProjectDir)..\..\..\Build\EmulatorX64\DEBUG_VS2017\X64\ + WindowsLocalDebugger + + \ No newline at end of file diff --git a/CdeEmuPkg/EmulatorPkg/build.sh b/CdeEmuPkg/EmulatorPkg/build.sh new file mode 100644 index 00000000000..76c22dfaf8d --- /dev/null +++ b/CdeEmuPkg/EmulatorPkg/build.sh @@ -0,0 +1,252 @@ +#!/bin/bash +# +# Copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +set -e +shopt -s nocasematch + + +# +# Setup workspace if it is not set +# +if [ -z "$WORKSPACE" ] +then + echo Initializing workspace + if [ ! -e `pwd`/edksetup.sh ] + then + cd .. + fi +# This version is for the tools in the BaseTools project. +# this assumes svn pulls have the same root dir +# export EDK_TOOLS_PATH=`pwd`/../BaseTools +# This version is for the tools source in edk2 + export EDK_TOOLS_PATH=`pwd`/BaseTools + echo $EDK_TOOLS_PATH + source edksetup.sh BaseTools +else + echo Building from: $WORKSPACE +fi + +# +# Configure defaults for various options +# + +PROCESSOR= +BUILDTARGET=DEBUG +BUILD_OPTIONS= +PLATFORMFILE= +LAST_ARG= +RUN_EMULATOR=no +CLEAN_TYPE=none +TARGET_TOOLS=GCC48 +NETWORK_SUPPORT= +BUILD_NEW_SHELL= +BUILD_FAT= +HOST_PROCESSOR=X64 + +case `uname` in + CYGWIN*) echo Cygwin not fully supported yet. ;; + Darwin*) + Major=$(uname -r | cut -f 1 -d '.') + if [[ $Major == 9 ]] + then + echo UnixPkg requires Snow Leopard or later OS + exit 1 + else + CLANG_VER=$(clang -ccc-host-triple x86_64-pc-win32-macho 2>&1 >/dev/null) || true + if [[ "$CLANG_VER" == *-ccc-host-triple* ]] + then + # only older versions of Xcode support -ccc-host-triple, for newer versions + # it is -target + HOST_TOOLS=XCODE5 + TARGET_TOOLS=XCODE5 + else + HOST_TOOLS=XCODE32 + TARGET_TOOLS=XCLANG + fi + fi + BUILD_NEW_SHELL="-D BUILD_NEW_SHELL" + BUILD_FAT="-D BUILD_FAT" + ;; + Linux*) + case `uname -m` in + i386) + HOST_PROCESSOR=IA32 + ;; + i686) + HOST_PROCESSOR=IA32 + ;; + x86_64) + HOST_PROCESSOR=X64 + ;; + esac + + gcc_version=$(gcc -v 2>&1 | tail -1 | awk '{print $3}') + case $gcc_version in + [1-3].*|4.[0-7].*) + echo EmulatorPkg requires GCC4.8 or later + exit 1 + ;; + 4.8.*) + TARGET_TOOLS=GCC48 + ;; + 4.9.*|6.[0-2].*) + TARGET_TOOLS=GCC49 + ;; + *) + TARGET_TOOLS=GCC5 + ;; + esac + ;; +esac + +# +# Scan command line to override defaults +# + +for arg in "$@" +do + if [ -z "$LAST_ARG" ]; then + case $arg in + -a|-b|-t|-p) + LAST_ARG=$arg + ;; + run) + RUN_EMULATOR=yes + shift + break + ;; + clean|cleanall) + CLEAN_TYPE=$arg + shift + break + ;; + *) + BUILD_OPTIONS="$BUILD_OPTIONS $arg" + ;; + esac + else + case $LAST_ARG in + -a) + PROCESSOR=$arg + ;; + -b) + BUILDTARGET=$arg + ;; + -p) + PLATFORMFILE=$arg + ;; + -t) + HOST_TOOLS=$arg + ;; + *) + BUILD_OPTIONS="$BUILD_OPTIONS $arg" + ;; + esac + LAST_ARG= + fi + shift +done +if [ -z "$HOST_TOOLS" ] +then + HOST_TOOLS=$TARGET_TOOLS +fi + +if [ -z "$PROCESSOR" ] +then + PROCESSOR=$HOST_PROCESSOR +fi + +BUILD_OUTPUT_DIR=$WORKSPACE/Build/Emulator$PROCESSOR + +case $PROCESSOR in + IA32) + ARCH_SIZE=32 + LIB_NAMES="ld-linux.so.2 libdl.so.2 crt1.o crti.o crtn.o" + LIB_SEARCH_PATHS="/usr/lib/i386-linux-gnu /usr/lib32 /lib32 /usr/lib /lib" + ;; + X64) + ARCH_SIZE=64 + LIB_NAMES="ld-linux-x86-64.so.2 libdl.so.2 crt1.o crti.o crtn.o" + LIB_SEARCH_PATHS="/usr/lib/x86_64-linux-gnu /usr/lib64 /lib64 /usr/lib /lib" + ;; +esac + +for libname in $LIB_NAMES +do + for dirname in $LIB_SEARCH_PATHS + do + if [ -e $dirname/$libname ]; then + export HOST_DLINK_PATHS="$HOST_DLINK_PATHS $dirname/$libname" + break + fi + done +done + +PLATFORMFILE=$WORKSPACE/EmulatorPkg/EmulatorPkg.dsc +BUILD_DIR="$BUILD_OUTPUT_DIR/${BUILDTARGET}_$TARGET_TOOLS" +BUILD_ROOT_ARCH=$BUILD_DIR/$PROCESSOR + +if [[ ! -f `which build` || ! -f `which GenFv` ]]; +then + # build the tools if they don't yet exist. Bin scheme + echo Building tools as they are not in the path + make -C $WORKSPACE/BaseTools +elif [[ ( -f `which build` || -f `which GenFv` ) && ! -d $EDK_TOOLS_PATH/Source/C/bin ]]; +then + # build the tools if they don't yet exist. BinWrapper scheme + echo Building tools no $EDK_TOOLS_PATH/Source/C/bin directory + make -C $WORKSPACE/BaseTools +else + echo using prebuilt tools +fi + + +if [[ "$RUN_EMULATOR" == "yes" ]]; then + case `uname` in + Darwin*) + cd $BUILD_ROOT_ARCH + /usr/bin/lldb \ + -o "command script import $WORKSPACE/EmulatorPkg/Unix/lldbefi.py" \ + -o 'script lldb.debugger.SetAsync(True)' \ + -o "run" ./Host + exit $? + ;; + esac + + /usr/bin/gdb $BUILD_ROOT_ARCH/Host -q -cd=$BUILD_ROOT_ARCH -x $WORKSPACE/EmulatorPkg/Unix/GdbRun.sh + exit +fi + +case $CLEAN_TYPE in + clean) + build -p $WORKSPACE/EmulatorPkg/EmulatorPkg.dsc -a $PROCESSOR -b $BUILDTARGET -t $HOST_TOOLS -n 3 clean + build -p $WORKSPACE/EmulatorPkg/EmulatorPkg.dsc -a $PROCESSOR -b $BUILDTARGET -t $TARGET_TOOLS -n 3 clean + exit $? + ;; + cleanall) + make -C $WORKSPACE/BaseTools clean + build -p $WORKSPACE/EmulatorPkg/EmulatorPkg.dsc -a $PROCESSOR -b $BUILDTARGET -t $HOST_TOOLS -n 3 clean + build -p $WORKSPACE/EmulatorPkg/EmulatorPkg.dsc -a $PROCESSOR -b $BUILDTARGET -t $TARGET_TOOLS -n 3 clean + build -p $WORKSPACE/ShellPkg/ShellPkg.dsc -a IA32 -b $BUILDTARGET -t $TARGET_TOOLS -n 3 clean + exit $? + ;; +esac + + +# +# Build the edk2 EmulatorPkg +# +if [[ $HOST_TOOLS == $TARGET_TOOLS ]]; then + build -p $WORKSPACE/EmulatorPkg/EmulatorPkg.dsc $BUILD_OPTIONS -a $PROCESSOR -b $BUILDTARGET -t $TARGET_TOOLS -D BUILD_$ARCH_SIZE $NETWORK_SUPPORT $BUILD_NEW_SHELL $BUILD_FAT -n 3 +else + build -p $WORKSPACE/EmulatorPkg/EmulatorPkg.dsc $BUILD_OPTIONS -a $PROCESSOR -b $BUILDTARGET -t $HOST_TOOLS -D BUILD_$ARCH_SIZE -D SKIP_MAIN_BUILD -n 3 modules + build -p $WORKSPACE/EmulatorPkg/EmulatorPkg.dsc $BUILD_OPTIONS -a $PROCESSOR -b $BUILDTARGET -t $TARGET_TOOLS -D BUILD_$ARCH_SIZE $NETWORK_SUPPORT $BUILD_NEW_SHELL $BUILD_FAT -n 3 + cp "$BUILD_OUTPUT_DIR/${BUILDTARGET}_$HOST_TOOLS/$PROCESSOR/Host" $BUILD_ROOT_ARCH +fi +exit $? + diff --git a/CdeEmuPkg/MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf b/CdeEmuPkg/MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf new file mode 100644 index 00000000000..9ac502a682a --- /dev/null +++ b/CdeEmuPkg/MdeModulePkg/Universal/DriverSampleDxe/DriverSampleDxe.inf @@ -0,0 +1,96 @@ +## @file +# This is a sample HII driver. +# +# This driver shows how HII protocol, VFR and UNI files are used to create a HII +# driver which can be displayed and configured by a UEFI HII Form Browser. +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DriverSample + MODULE_UNI_FILE = DriverSample.uni + FILE_GUID = FE3542FE-C1D3-4EF8-657C-8048606FF671 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = DriverSampleInit + UNLOAD_IMAGE = DriverSampleUnload + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + MdeModulePkg\Universal\DriverSampleDxe\DriverSample.c + MdeModulePkg\Universal\DriverSampleDxe\InventoryStrings.uni + MdeModulePkg\Universal\DriverSampleDxe\NVDataStruc.h + MdeModulePkg\Universal\DriverSampleDxe\VfrStrings.uni + MdeModulePkg\Universal\DriverSampleDxe\DriverSample.h + MdeModulePkg\Universal\DriverSampleDxe\Inventory.vfr + Vfr.vfr + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + + +[LibraryClasses] + BaseLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeServicesTableLib + BaseMemoryLib + DebugLib + HiiLib + PrintLib + UefiLib + DevicePathLib + +[Guids] + gEfiIfrTianoGuid ## PRODUCES ## UNDEFINED + gDriverSampleInventoryGuid ## CONSUMES ## HII + ## SOMETIMES_PRODUCES ## Event + ## CONSUMES ## Event + gEfiIfrRefreshIdOpGuid + ## CONSUMES ## HII + ## PRODUCES ## Variable:L"MyIfrNVData" + ## SOMETIMES_CONSUMES ## Variable:L"MyIfrNVData" + ## PRODUCES ## Variable:L"MyEfiVar" + ## SOMETIMES_CONSUMES ## Variable:L"MyEfiVar" + ## PRODUCES ## GUID # HiiConstructConfigHdr MyEfiVar + ## PRODUCES ## GUID # HiiConstructConfigHdr MyIfrNVData + ## SOMETIMES_CONSUMES ## GUID # HiiIsConfigHdrMatch MyEfiVar + ## SOMETIMES_CONSUMES ## GUID # HiiIsConfigHdrMatch MyIfrNVData + ## SOMETIMES_PRODUCES ## GUID # HiiGetBrowserData MyIfrNVData + ## SOMETIMES_CONSUMES ## GUID # HiiSetBrowserData MyIfrNVData + ## SOMETIMES_PRODUCES ## GUID # HiiGetBrowserData MyEfiVar + ## SOMETIMES_CONSUMES ## GUID # HiiSetBrowserData MyEfiVar + gDriverSampleFormSetGuid + +[Protocols] + ## PRODUCES # DriverSampleFormSet + ## PRODUCES # DriverSampleInventory + gEfiDevicePathProtocolGuid + gEfiHiiStringProtocolGuid ## CONSUMES + gEfiHiiConfigRoutingProtocolGuid ## CONSUMES + gEfiHiiConfigAccessProtocolGuid ## PRODUCES + gEfiFormBrowser2ProtocolGuid ## CONSUMES + gEfiHiiDatabaseProtocolGuid ## CONSUMES + gEfiSimpleTextInputExProtocolGuid ## SOMETIMES_CONSUMES + gEdkiiFormBrowserExProtocolGuid ## CONSUMES + gEfiConfigKeywordHandlerProtocolGuid ## CONSUMES + gEfiHiiPopupProtocolGuid ## CONSUMES + +[Depex] + gEfiSimpleTextOutProtocolGuid AND gEfiHiiDatabaseProtocolGuid AND gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + DriverSampleExtra.uni diff --git a/CdeEmuPkg/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr b/CdeEmuPkg/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr new file mode 100644 index 00000000000..28b4a2784c9 --- /dev/null +++ b/CdeEmuPkg/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr @@ -0,0 +1,968 @@ +///** @file +// +// Sample Setup formset. +// +// Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
+// (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+// SPDX-License-Identifier: BSD-2-Clause-Patent +// +//**/ + + +#include +#include "NVDataStruc.h" + +// +// Formset class used by Device Manager +// +#define EFI_NON_DEVICE_CLASS 0x00 +#define EFI_DISK_DEVICE_CLASS 0x01 +#define EFI_VIDEO_DEVICE_CLASS 0x02 +#define EFI_NETWORK_DEVICE_CLASS 0x04 +#define EFI_INPUT_DEVICE_CLASS 0x08 +#define EFI_ON_BOARD_DEVICE_CLASS 0x10 +#define EFI_OTHER_DEVICE_CLASS 0x20 + +// +// Formset subclass +// +#define EFI_SETUP_APPLICATION_SUBCLASS 0x00 +#define EFI_GENERAL_APPLICATION_SUBCLASS 0x01 +#define EFI_FRONT_PAGE_SUBCLASS 0x02 +#define EFI_SINGLE_USE_SUBCLASS 0x03 + +#define EFI_USER_INFO_ACCESS_SETUP_ADMIN_GUID \ + { 0x85b75607, 0xf7ce, 0x471e, { 0xb7, 0xe4, 0x2a, 0xea, 0x5f, 0x72, 0x32, 0xee } } + +#define PERL_GUID \ + { 0x63E60A51, 0x497D, 0xD427, {0xC4, 0xA5, 0xB8, 0xAB, 0xDC, 0x3A, 0xAE, 0xB6 }} + +// +// Labels definition +// +#define LABEL_1_VALUE 0x01 +#define LABEL_2_VALUE 0x1000 +#define LABEL_UPDATE_BBS 0x2222 + +formset + guid = DRIVER_SAMPLE_FORMSET_GUID, + title = STRING_TOKEN(STR_FORM_SET_TITLE), + help = STRING_TOKEN(STR_FORM_SET_TITLE_HELP), + classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID, + + // + // Notes: VfrCompiler will insert a Standard Default Storage declaration + // after the formset declaration. >00000040: 5C 06 00 00 00 00. + // So we don't need to declare the Standard Default. + // Please check the vfr.lst file for details. + // To enable list file for VFR, add "-l" to VfrCompile in [Build.Visual-Form-Representation-File] as follows: + // VfrCompile -l --no-pre-processing --output-directory ${d_path} $(OUTPUT_DIR)(+)${s_dir}(+)${s_base}.iii + // + + // + // Define a Buffer Storage (EFI_IFR_VARSTORE) + // + varstore DRIVER_SAMPLE_CONFIGURATION, // This is the data structure type + varid = CONFIGURATION_VARSTORE_ID, // Optional VarStore ID + name = MyIfrNVData, // Define referenced name in vfr + guid = DRIVER_SAMPLE_FORMSET_GUID; // GUID of this buffer storage + + // + // Define a EFI variable Storage (EFI_IFR_VARSTORE_EFI) + // + efivarstore MY_EFI_VARSTORE_DATA, + attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, // EFI variable attribures + name = MyEfiVar, + guid = DRIVER_SAMPLE_FORMSET_GUID; + + // + // Define a Buffer Storage (EFI_IFR_VARSTORE) + // + efivarstore MY_EFI_BITS_VARSTORE_DATA, // This is the data structure type + attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, // EFI variable attribures + name = MyEfiBitVar, // Define referenced name in vfr + guid = DRIVER_SAMPLE_FORMSET_GUID; // GUID of this buffer storage + + efivarstore MY_EFI_UNION_DATA, + attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, // EFI variable attribures + name = MyEfiUnionVar, + guid = DRIVER_SAMPLE_FORMSET_GUID; + + // + // Define a Name/Value Storage (EFI_IFR_VARSTORE_NAME_VALUE) + // + namevaluevarstore MyNameValueVar, // Define storage reference name in vfr + name = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME0), // Define Name list of this storage, refer it by MyNameValueVar[0] + name = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME1), // Define Name list of this storage, refer it by MyNameValueVar[1] + name = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME2), // Define Name list of this storage, refer it by MyNameValueVar[2] + guid = DRIVER_SAMPLE_FORMSET_GUID; // GUID of this Name/Value storage + + defaultstore MyStandardDefault, + prompt = STRING_TOKEN(STR_STANDARD_DEFAULT_PROMPT), + attribute = 0x0000; // Default ID: 0000 standard default + + defaultstore MyManufactureDefault, + prompt = STRING_TOKEN(STR_MANUFACTURE_DEFAULT_PROMPT), + attribute = 0x0001; // Default ID: 0001 manufacture default + + // + // Define a Form (EFI_IFR_FORM) + // + form formid = 1, // Form ID + title = STRING_TOKEN(STR_FORM1_TITLE); // Form title + + subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT); + + subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT2); + + // + // Define a display only text (EFI_IFR_TEXT) + // + text + help = STRING_TOKEN(STR_TEXT_HELP), // Help string + text = STRING_TOKEN(STR_CPU_STRING), // Prompt string + text = STRING_TOKEN(STR_CPU_STRING2); // TextTwo + + // + // Define action button (EFI_IFR_ACTION) + // + text + help = STRING_TOKEN(STR_EXIT_TEXT), + text = STRING_TOKEN(STR_EXIT_TEXT), + flags = INTERACTIVE, // VfrCompiler will generate opcode EFI_IFR_ACTION for Text marked as INTERACTIVE + key = 0x1237; + + text + help = STRING_TOKEN(STR_SAVE_TEXT), + text = STRING_TOKEN(STR_SAVE_TEXT), + flags = INTERACTIVE, + key = 0x1238; + + text + help = STRING_TOKEN(STR_SAVE_CURRENT), + text = STRING_TOKEN(STR_SAVE_CURRENT), + flags = INTERACTIVE, + key = 0x1243; + + text + help = STRING_TOKEN(STR_DISCARD_CURRENT_AND_EXIT), + text = STRING_TOKEN(STR_DISCARD_CURRENT_AND_EXIT), + flags = INTERACTIVE, + key = 0x1244; + // + // Define oneof (EFI_IFR_ONE_OF) + // + oneof name = MyOneOf, // Define reference name for Question + varid = MyIfrNVData.SuppressGrayOutSomething, // Use "DataStructure.Member" to reference Buffer Storage + prompt = STRING_TOKEN(STR_ONE_OF_PROMPT), + help = STRING_TOKEN(STR_ONE_OF_HELP), + // + // Define an option (EFI_IFR_ONE_OF_OPTION) + // + option text = STRING_TOKEN(STR_ONE_OF_TEXT4), value = 0x0, flags = 0; + option text = STRING_TOKEN(STR_ONE_OF_TEXT5), value = 0x1, flags = 0; + // + // DEFAULT indicate this option will be marked with EFI_IFR_OPTION_DEFAULT + // + option text = STRING_TOKEN(STR_ONE_OF_TEXT6), value = 0x2, flags = DEFAULT; + endoneof; + + oneof varid = MyIfrNVData.BootOrderLarge, + prompt = STRING_TOKEN(STR_ONE_OF_PROMPT), + help = STRING_TOKEN(STR_ONE_OF_HELP), + default value = cond (pushthis == 0 ? 0 : cond ((questionref(MyOneOf) >> 0x4 & 0xF00) == 0x0 + 0x2 ? 0 : 1)), + option text = STRING_TOKEN(STR_BOOT_ORDER1), value = 0x0, flags = 0; + option text = STRING_TOKEN(STR_BOOT_ORDER2), value = 0x1, flags = 0; + endoneof; + + grayoutif ideqval MyIfrNVData.SuppressGrayOutSomething == 0x1; + suppressif questionref(MyOneOf) == 0x0; + + checkbox varid = MyIfrNVData.ChooseToActivateNuclearWeaponry, + prompt = STRING_TOKEN(STR_CHECK_BOX_PROMPT), + help = STRING_TOKEN(STR_CHECK_BOX_HELP), + // + // CHECKBOX_DEFAULT indicate this checkbox is marked with EFI_IFR_CHECKBOX_DEFAULT + // CHECKBOX_DEFAULT_MFG indicate EFI_IFR_CHECKBOX_DEFAULT_MFG. + // + flags = CHECKBOX_DEFAULT | CHECKBOX_DEFAULT_MFG, + default = TRUE, + endcheckbox; + endif; + endif; + + // + // Ordered list: + // sizeof(MyIfrNVData) storage must be UINT8 array, and + // size written for the variable must be size of the entire + // variable. + // + // + suppressif ideqval MyIfrNVData.SuppressGrayOutSomething == 0x0; + + // + // label is defined as an anchor where you want to insert some dynamic + // opcodes created on-the-fly + // + label LABEL_UPDATE_BBS; + + orderedlist + varid = MyIfrNVData.BootOrder, + prompt = STRING_TOKEN(STR_BOOT_OPTIONS), + help = STRING_TOKEN(STR_NULL_STRING), + flags = RESET_REQUIRED, + option text = STRING_TOKEN(STR_BOOT_OPTION2), value = 2, flags = 0; + option text = STRING_TOKEN(STR_BOOT_OPTION1), value = 1, flags = 0; + option text = STRING_TOKEN(STR_BOOT_OPTION3), value = 3, flags = 0; + suppressif ideqval MyIfrNVData.BootOrderLarge == 0; + option text = STRING_TOKEN(STR_BOOT_OPTION4), value = 4, flags = 0; + endif; + endlist; + + // + // label should be paired with each other + // + label LABEL_END; + + endif; // end suppressif + + disableif ideqval MyIfrNVData.SuppressGrayOutSomething == 0x2; + orderedlist + varid = MyIfrNVData.OrderedList, + prompt = STRING_TOKEN(STR_TEST_OPCODE), + help = STRING_TOKEN(STR_TEXT_HELP), + flags = RESET_REQUIRED, + option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 3, flags = 0; + option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 2, flags = 0; + option text = STRING_TOKEN(STR_ONE_OF_TEXT3), value = 1, flags = 0; + default = {1,2,3}, + endlist; + endif; + + label 100; + + // + // Define a hyperlink (EFI_IFR_REF) + // + goto 0x1234, // Destination Form ID + prompt = STRING_TOKEN(STR_GOTO_DYNAMIC), // Prompt string + help = STRING_TOKEN(STR_GOTO_HELP), // Help string + flags = INTERACTIVE, // INTERACTIVE indicate it's marked with EFI_IFR_FLAG_CALLBACK + key = 0x1234; // Question ID which will be passed-in in COnfigAccess.Callback() + + goto 0x1234, + prompt = STRING_TOKEN(STR_GOTO_DYNAMIC2), + help = STRING_TOKEN(STR_GOTO_HELP), + flags = INTERACTIVE, + key = 0x1235; + + oneof varid = MyIfrNVData.TestLateCheck, + prompt = STRING_TOKEN(STR_TEST_OPCODE), + help = STRING_TOKEN(STR_ONE_OF_HELP), + flags = RESET_REQUIRED, + option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 0, flags = 0; + option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 1, flags = DEFAULT; + warningif prompt = STRING_TOKEN(STR_WARNING_POPUP), timeout = 5, + ideqval MyIfrNVData.TestLateCheck == 0 + endif; + + endoneof; + + oneof varid = MyIfrNVData.TestLateCheck2, + prompt = STRING_TOKEN(STR_TEST_OPCODE2), + help = STRING_TOKEN(STR_ONE_OF_HELP), + flags = RESET_REQUIRED, + option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 0, flags = DEFAULT; + option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 1, flags = 0; + + inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP), + ideqid MyIfrNVData.TestLateCheck == MyIfrNVData.TestLateCheck2 + endif; + + endoneof; + + oneof varid = MyIfrNVData.QuestionAboutTreeHugging, + prompt = STRING_TOKEN(STR_ONE_OF_PROMPT_KEYWORD), + help = STRING_TOKEN(STR_ONE_OF_HELP), + flags = RESET_REQUIRED, + option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 0, flags = 0; + option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 1, flags = DEFAULT; + option text = STRING_TOKEN(STR_ONE_OF_TEXT3), value = 3, flags = 0; + endoneof; +/*kgtest*/ + // + // This is an HII option which has REST_STYLE flag and x-UEFI namespace + // UNI string associated. This HII option could be configured by either in-band + // edk2 setup browser or the remote management in out-of-band such as Redfish + // service. This HII option is configured through EFI_KEYWORD_HANDLER_PROTOCOL. + // + oneof varid = MyIfrNVData.QuestionXUefiKeywordRestStyle, + prompt = STRING_TOKEN(STR_ONE_OF_PROMPT_X_UEFI), + help = STRING_TOKEN(STR_ONE_OF_PROMPT_X_UEFI_HELP), + flags = RESET_REQUIRED /*| REST_STYLE*/, + option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 0, flags = 0; + option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 1, flags = DEFAULT; + option text = STRING_TOKEN(STR_ONE_OF_TEXT3), value = 3, flags = 0; + endoneof; + + + // + // This is a HII option which has REST_STYLE flag but without the x-UEFI namespace + // UNI string associated. This HII option could be configured by either + // setup browser or the remote management in out-of-band such as Redfish + // service. This HII option is configured through EFI HII Configuration Routing + // Protocol becasue it doesn't have x-UEFI namespace UNI string. + // + numeric varid = MyIfrNVData.QuestionNonXUefiKeywordRestStyle, + prompt = STRING_TOKEN(STR_ONE_OF_PROMPT_NON_X_UEFI), + help = STRING_TOKEN(STR_ONE_OF_PROMPT_NON_X_UEFI_HELP), + flags = RESET_REQUIRED /*| REST_STYLE*/, + minimum = 0, + maximum = 0xf0, + step = 0, // Stepping of 0 equates to a manual entering + // of a value, otherwise it will be adjusted by "+"/"-" + default = 0, // defaultstore could be used to specify the default type + // If no defaultstore is specified, it implies Standard Default + endnumeric; +/*kgtest*/ + // + // Define a string (EFI_IFR_STRING) + // + string varid = MyIfrNVData.MyStringData, + prompt = STRING_TOKEN(STR_MY_STRING_PROMPT2), + help = STRING_TOKEN(STR_MY_STRING_HELP2), + flags = INTERACTIVE, + key = 0x1236, + minsize = 6, + maxsize = 40, + inconsistentif prompt = STRING_TOKEN(STR_STRING_CHECK_ERROR_POPUP), + pushthis != stringref(STRING_TOKEN(STR_STRING_CHECK)) + endif; + endstring; + + // + // Define a numeric (EFI_IFR_NUMERIC) + // + numeric varid = MyIfrNVData.HowOldAreYouInYearsManual, + prompt = STRING_TOKEN(STR_NUMERIC_READONLY_PROMPT), + help = STRING_TOKEN(STR_NUMERIC_HELP0), + flags = READ_ONLY, // READ_ONLY indicate it's marked with EFI_IFR_FLAG_READ_ONLY + minimum = 0, + maximum = 0xf0, + step = 0, // Stepping of 0 equates to a manual entering + // of a value, otherwise it will be adjusted by "+"/"-" + default = 21, // defaultstore could be used to specify the default type + // If no defaultstore is specified, it implies Standard Default + + endnumeric; + + numeric varid = MyIfrNVData.HowOldAreYouInYearsManual, + prompt = STRING_TOKEN(STR_NUMERIC_MANUAL_PROMPT), + help = STRING_TOKEN(STR_NUMERIC_HELP0), + minimum = 0, + maximum = 0xf0, + step = 0, + default value = questionrefval(devicepath = STRING_TOKEN (STR_DEVICE_PATH), guid = DRIVER_SAMPLE_FORMSET_GUID, 0x1111), + + inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP), + ideqval MyIfrNVData.HowOldAreYouInYearsManual == 99 + OR + ideqid MyIfrNVData.HowOldAreYouInYearsManual == MyEfiVar.Field8 + OR + ideqvallist MyIfrNVData.HowOldAreYouInYearsManual == 1 3 5 7 + endif; + + endnumeric; + + numeric varid = MyEfiVar.Field8, // Reference of EFI variable storage + questionid = 0x1111, + prompt = STRING_TOKEN(STR_TALL_HEX_PROMPT), + help = STRING_TOKEN(STR_NUMERIC_HELP1), + flags = DISPLAY_UINT_HEX | INTERACTIVE, // Display in HEX format (if not specified, default is in decimal format) + minimum = 0, + maximum = 250, + default = 18, defaultstore = MyStandardDefault, // This is standard default value + default = 19, defaultstore = MyManufactureDefault, // This is manufacture default value + + endnumeric; + + // + // Define numeric using Name/Value Storage + // + numeric varid = MyNameValueVar[0], // This numeric take NameValueVar0 as storage + prompt = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME0), + help = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME0_HELP), + // + // Size should be defined for numeric when use Name/Value storage + // Valid value for numerice size are: NUMERIC_SIZE_1, NUMERIC_SIZE_2, NUMERIC_SIZE_4 and NUMERIC_SIZE_8 + // + flags = NUMERIC_SIZE_1, // Size of this numeric is 1 byte + minimum = 0, + maximum = 0xff, + step = 0, + locked, + default = 16, defaultstore = MyStandardDefault, // This is standard default value + default = 17, defaultstore = MyManufactureDefault, // This is manufacture default value + endnumeric; + + numeric varid = MyNameValueVar[1], // This numeric take NameValueVar1 as storage + prompt = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME1), + help = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME1_HELP), + flags = NUMERIC_SIZE_2, // Size of this numeric is 2 bytes + minimum = 0, + maximum = 0xffff, + step = 0, + default = 18, defaultstore = MyStandardDefault, // This is standard default value + default = 19, defaultstore = MyManufactureDefault, // This is manufacture default value + endnumeric; + + // + // Define string using Name/Value Storage + // + string varid = MyNameValueVar[2], // This string take NameValueVar2 as storage + prompt = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME2), + help = STRING_TOKEN(STR_NAME_VALUE_VAR_NAME2_HELP), + minsize = 2, + maxsize = 0x14, + endstring; + + oneof varid = MyEfiVar.Field16, + prompt = STRING_TOKEN(STR_ONE_OF_PROMPT), + help = STRING_TOKEN(STR_NUMERIC_NUM_HELP), + option text = STRING_TOKEN(STR_BOOT_ORDER1), value = 0x0, flags = 0; + option text = STRING_TOKEN(STR_BOOT_ORDER2), value = 0x1, flags = DEFAULT; + endoneof; + + label LABEL_1_VALUE; + label LABEL_2_VALUE; + + grayoutif ideqval MyIfrNVData.HowOldAreYouInYearsManual == 23 AND ideqval MyIfrNVData.SuppressGrayOutSomething == 0x1; + numeric varid = MyIfrNVData.HowOldAreYouInYears, + prompt = STRING_TOKEN(STR_NUMERIC_STEP_PROMPT), + help = STRING_TOKEN(STR_NUMERIC_HELP2), + minimum = 0, + maximum = 243, + step = 1, + default = 18, defaultstore = MyStandardDefault, // This is standard default value + default = 19, defaultstore = MyManufactureDefault, // This is manufacture default value + + endnumeric; + endif; + + numeric varid = MyIfrNVData.GetDefaultValueFromAccess, + questionid = 0x1239, + prompt = STRING_TOKEN(STR_DEFAULT_VALUE_FROM_ACCESS_PROMPT), + help = STRING_TOKEN(STR_DEFAULT_VALUE_FROM_ACCESS_HELP), + flags = DISPLAY_UINT_HEX | INTERACTIVE, + minimum = 0, + maximum = 255, + step = 1, + default = 18, + endnumeric; + + numeric varid = MyIfrNVData.GetDefaultValueFromCallBack, + questionid = 0x1240, + prompt = STRING_TOKEN(STR_DEFAULT_VALUE_FROM_CALLBACK_PROMPT), + help = STRING_TOKEN(STR_DEFAULT_VALUE_FROM_CALLBACK_HELP), + flags = DISPLAY_UINT_HEX | INTERACTIVE, + minimum = 0, + maximum = 255, + step = 1, + default = 18, + endnumeric; + + orderedlist + varid = MyIfrNVData.GetDefaultValueFromCallBackForOrderedList, + questionid = 0x1252, + prompt = STRING_TOKEN(STR_DEFAULT_VALUE_FROM_CALLBACK_PROMPT), + help = STRING_TOKEN(STR_DEFAULT_VALUE_FROM_CALLBACK_HELP), + flags = INTERACTIVE, + option text = STRING_TOKEN(STR_ONE_OF_TEXT1), value = 1, flags = 0; + option text = STRING_TOKEN(STR_ONE_OF_TEXT2), value = 2, flags = 0; + option text = STRING_TOKEN(STR_ONE_OF_TEXT3), value = 3, flags = 0; + endlist; + + resetbutton + defaultstore = MyStandardDefault, + prompt = STRING_TOKEN(STR_STANDARD_DEFAULT_PROMPT), + help = STRING_TOKEN(STR_STANDARD_DEFAULT_HELP), + endresetbutton; + + resetbutton + defaultstore = MyManufactureDefault, + prompt = STRING_TOKEN(STR_MANUFACTURE_DEFAULT_PROMPT), + help = STRING_TOKEN(STR_MANUFACTURE_DEFAULT_HELP), + endresetbutton; + + // + // Sample use case for IFR Security op-code + // + grayoutif NOT security (EFI_USER_INFO_ACCESS_SETUP_ADMIN_GUID); + text + help = STRING_TOKEN(STR_TEXT_SECRUITY_TEST_HELP), + text = STRING_TOKEN(STR_TEXT_SECRUITY_TEST_TEXT); + endif; + + numeric varid = MyEfiVar.SubmittedCallback, + questionid = 0x1250, + prompt = STRING_TOKEN(STR_SUBMITTED_CALLBACK_TEST_PROMPT), + help = STRING_TOKEN(STR_SUBMITTED_CALLBACK_TEST_HELP), + flags = INTERACTIVE, + minimum = 0, + maximum = 255, + default = 18, + endnumeric; + + text + help = STRING_TOKEN(STR_POPUP_TEST_HELP), + text = STRING_TOKEN(STR_POPUP_TEST_PROMPT), + flags = INTERACTIVE, + key = 0x1330; + + goto 2, + prompt = STRING_TOKEN(STR_GOTO_FORM2), //SecondSetupPage // this too has no end-op and basically it's a jump to a form ONLY + help = STRING_TOKEN(STR_GOTO_HELP); + + goto 3, + prompt = STRING_TOKEN(STR_GOTO_FORM3), //ThirdSetupPage // this too has no end-op and basically it's a jump to a form ONLY + help = STRING_TOKEN(STR_GOTO_HELP); + + goto 4, + prompt = STRING_TOKEN(STR_GOTO_FORM4), //FourthSetupPage // this too has no end-op and basically it's a jump to a form ONLY + help = STRING_TOKEN(STR_GOTO_HELP); + + goto 5, + prompt = STRING_TOKEN(STR_GOTO_FORM5), //FifthSetupPage // this too has no end-op and basically it's a jump to a form ONLY + help = STRING_TOKEN(STR_GOTO_FORM5_HELP); + + goto 6, + prompt = STRING_TOKEN(STR_GOTO_FORM6), //SixthSetupPage // this too has no end-op and basically it's a jump to a form ONLY + help = STRING_TOKEN(STR_GOTO_HELP); + + goto + formsetguid = DRIVER_SAMPLE_INVENTORY_GUID, + formid = 0x1, + question = 0x1, + prompt = STRING_TOKEN(STR_GOTO_ANOTHER_FORMSET), + help = STRING_TOKEN(STR_GOTO_ANOTHER_FORMSET_HELP); + + guidop + guid = DRIVER_SAMPLE_FORMSET_GUID, + datatype = MY_EFI_VARSTORE_DATA, + data.Field8 = 0x21, + data.Field16 = 0x2121, + data.OrderedList[0] = 0x21, + endguidop; + + goto 7, + prompt = STRING_TOKEN(STR_GOTO_FORM7), + help = STRING_TOKEN(STR_GOTO_FORM7_HELP); + + endform; + + suppressif ideqval MyIfrNVData.BootOrderLarge == 0; + form formid = 2, // SecondSetupPage, + title = STRING_TOKEN(STR_FORM2_TITLE); // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code + + date + name = Date, + prompt = STRING_TOKEN(STR_DATE_PROMPT), + help = STRING_TOKEN(STR_DATE_HELP), + flags = STORAGE_TIME, + default = 2004/1/1, + + inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP), + ideqval Date.Day == 31 + AND + ideqvallist Date.Month == 2 4 6 9 11 + endif; + + // + // If the day is 30 AND month is 2 + // + inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP), + ideqval Date.Day == 30 + AND + ideqval Date.Month == 2 + endif; + + // + // If the day is 29 AND month is 2 AND it year is NOT a leapyear + // + inconsistentif prompt = STRING_TOKEN(STR_ERROR_POPUP), + ideqval Date.Day == 0x1D + AND + ideqval Date.Month == 2 + AND + NOT + ideqvallist Date.Year == 2004 2008 20012 20016 2020 2024 2028 2032 2036 + endif; + + enddate; + + text + help = STRING_TOKEN(STR_SAVE_CURRENT_AND_EXIT), + text = STRING_TOKEN(STR_SAVE_CURRENT_AND_EXIT), + flags = INTERACTIVE, + key = 0x1241; + + text + help = STRING_TOKEN(STR_DISCARD_CURRENT), + text = STRING_TOKEN(STR_DISCARD_CURRENT), + flags = INTERACTIVE, + key = 0x1242; + + time + prompt = STRING_TOKEN(STR_TIME_PROMPT), + help = STRING_TOKEN(STR_TIME_HELP), + flags = STORAGE_TIME, + endtime; + + time + name = MyTime, + varid = MyIfrNVData.Time, + prompt = STRING_TOKEN(STR_TIME_PROMPT), + help = STRING_TOKEN(STR_TIME_PROMPT), + flags = STORAGE_NORMAL | SECOND_SUPPRESS, + default = 15:33:33, + endtime; + + checkbox varid = MyIfrNVData.ChooseToActivateNuclearWeaponry, + prompt = STRING_TOKEN(STR_CHECK_BOX_PROMPT), + help = STRING_TOKEN(STR_CHECK_BOX_HELP), + flags = CHECKBOX_DEFAULT, + endcheckbox; + + text + help = STRING_TOKEN(STR_TEXT_HELP), + text = STRING_TOKEN(STR_TEXT_TEXT_1); + + text + help = STRING_TOKEN(STR_TEXT_HELP), + text = STRING_TOKEN(STR_TEXT_TEXT_1), + text = STRING_TOKEN(STR_TEXT_TEXT_2); + + goto 1, + prompt = STRING_TOKEN(STR_GOTO_FORM1), //MainSetupPage // this too has no end-op and basically it's a jump to a form ONLY + help = STRING_TOKEN(STR_GOTO_HELP); + + goto + varid = MyIfrNVData.RefData, + prompt = STRING_TOKEN(STR_GOTO_DYNAMIC3), + help = STRING_TOKEN(STR_GOTO_DYNAMIC3_HELP), + flags = INTERACTIVE, + key = 0x1248, + // + // Set the defult value, format is QuestionId; FormId; FormsetGuid; Device Path String Token + // + default = 0;0;ZERO_GUID;STRING_TOKEN(STR_NULL_STRING), + ; // goto opcode end flag. + + goto + prompt = STRING_TOKEN(STR_GOTO_DYNAMIC4), + help = STRING_TOKEN(STR_GOTO_DYNAMIC4_HELP), + flags = INTERACTIVE, + key = 0x1249; + + endform; + endif; + + form formid = 3, title = STRING_TOKEN(STR_FORM3_TITLE); // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code + + suppressif ideqval MyEfiVar.Field8 == 111; + text + help = STRING_TOKEN(STR_TEXT_HELP), + text = STRING_TOKEN(STR_TEXT_TEXT_1); + endif; + + goto 1, + prompt = STRING_TOKEN(STR_GOTO_FORM1), //MainSetupPage + help = STRING_TOKEN(STR_GOTO_HELP); + + numeric varid = MyIfrNVData.DynamicRefresh, + prompt = STRING_TOKEN(STR_NUMERIC_MANUAL_PROMPT), + help = STRING_TOKEN(STR_NUMERIC_HELP0), + flags = INTERACTIVE, + key = 0x5678, + minimum = 0, + maximum = 0xff, + step = 0, + default = 0, + refresh interval = 3 // Refresh interval in seconds + endnumeric; + + grayoutif match2 (stringref(STRING_TOKEN(STR_PATTERN)), stringref(STRING_TOKEN(STR_STRING)), PERL_GUID); + numeric + varid = MyIfrNVData.Match2, + prompt = STRING_TOKEN(STR_MATCH2_PROMPT), + help = STRING_TOKEN(STR_MATCH2_HELP), + minimum = 0, + maximum = 243, + endnumeric; + endif; + + label LABEL_UPDATE2; + label LABEL_END; + + endform; + + formmap formid = 4, + maptitle = STRING_TOKEN(STR_SAMPL_MAP_METHOD); + mapguid = DRIVER_SAMPLE_FORMSET_GUID; + maptitle = STRING_TOKEN(STR_STANDARD_MAP_METHOD); + mapguid = EFI_HII_STANDARD_FORM_GUID; + + oneof varid = MyIfrNVData.SerialPortNo, + prompt = STRING_TOKEN(STR_SERIAL_PORT), + help = STRING_TOKEN(STR_ONE_OF_HELP), + + read cond (get(MyIfrNVData.SerialPortStatus) != 0 ? 0 : cond ((get(MyIfrNVData.SerialPortIo) & 0xF00) >> 0x8 == get(MyIfrNVData.SerialPortIrq) - 1 ? UNDEFINED : map (get(MyIfrNVData.SerialPortIo) : 0x3f8,1; 0x2F8,2; 0x3E8,3; 0x2E8,4;))); + write set(MyIfrNVData.SerialPortStatus, pushthis != 0) AND set(MyIfrNVData.SerialPortIo, map (pushthis : 1,0x3F8; 2,0x2F8; 3,0x3E8; 4,0x2E8;)) AND set (MyIfrNVData.SerialPortIrq, map (pushthis: 1,4; 2,3; 3,4; 4,3;)); + + option text = STRING_TOKEN(STR_SERIAL_PORT_DISABLE), value = 0x0, flags = DEFAULT; + option text = STRING_TOKEN(STR_SERIAL_PORT1), value = 0x1, flags = 0; + option text = STRING_TOKEN(STR_SERIAL_PORT2), value = 0x2, flags = 0; + option text = STRING_TOKEN(STR_SERIAL_PORT3), value = 0x3, flags = 0; + option text = STRING_TOKEN(STR_SERIAL_PORT4), value = 0x4, flags = 0; + endoneof; + + grayoutif TRUE; + checkbox varid = MyIfrNVData.SerialPortStatus, + prompt = STRING_TOKEN(STR_SERIAL_PORT_STATUS), + help = STRING_TOKEN(STR_CHECK_BOX_HELP), + endcheckbox; + endif; + + grayoutif TRUE; + suppressif ideqval MyIfrNVData.SerialPortStatus == 0; + oneof varid = MyIfrNVData.SerialPortIo, + prompt = STRING_TOKEN(STR_SERIAL_PORT_IO_ADDRESS), + help = STRING_TOKEN(STR_ONE_OF_HELP), + + option text = STRING_TOKEN(STR_SERIAL_PORT1_IOADDR), value = 0x3F8, flags = DEFAULT; + option text = STRING_TOKEN(STR_SERIAL_PORT2_IOADDR), value = 0x2F8, flags = 0; + option text = STRING_TOKEN(STR_SERIAL_PORT3_IOADDR), value = 0x3E8, flags = 0; + option text = STRING_TOKEN(STR_SERIAL_PORT4_IOADDR), value = 0x2E8, flags = 0; + endoneof; + endif; + endif; + + grayoutif TRUE; + suppressif ideqval MyIfrNVData.SerialPortStatus == 0; + oneof varid = MyIfrNVData.SerialPortIrq, + prompt = STRING_TOKEN(STR_SERIAL_PORT_IRQ), + help = STRING_TOKEN(STR_ONE_OF_HELP), + + option text = STRING_TOKEN(STR_SERIAL_PORT13_IRQ), value = 0x4, flags = DEFAULT; + option text = STRING_TOKEN(STR_SERIAL_PORT24_IRQ), value = 0x3, flags = 0; + endoneof; + endif; + endif; + + goto 1, + prompt = STRING_TOKEN(STR_GOTO_FORM1), //MainSetupPage + help = STRING_TOKEN(STR_GOTO_HELP); + + endform; + + form formid = 5, // Modal form + title = STRING_TOKEN(STR_MODAL_FORM_TITLE); + // + // This form is a modal form. + // + modal; + text + help = STRING_TOKEN(STR_EXIT_TEXT), + text = STRING_TOKEN(STR_EXIT_TEXT), + flags = INTERACTIVE, // VfrCompiler will generate opcode EFI_IFR_ACTION for Text marked as INTERACTIVE + key = 0x1245; + + text + help = STRING_TOKEN(STR_SAVE_TEXT), + text = STRING_TOKEN(STR_SAVE_TEXT), + flags = INTERACTIVE, // VfrCompiler will generate opcode EFI_IFR_ACTION for Text marked as INTERACTIVE + key = 0x1246; + endform; + + form formid = 6, // Form to show the refresh guid group op-code + title = STRING_TOKEN(STR_FORM6_TITLE); + + text + help = STRING_TOKEN(STR_TEXT_REFRESH_GUID), + text = STRING_TOKEN(STR_TEXT_REFRESH_GUID); + + numeric varid = MyIfrNVData.RefreshGuidCount, + prompt = STRING_TOKEN(STR_TEXT_REFRESH_GUID_COUNT), + help = STRING_TOKEN(STR_NUMERIC_HELP0), + flags = INTERACTIVE, + key = 0x1247, + minimum = 0, + maximum = 0xff, + step = 0, + default = 0, + refreshguid = EFI_IFR_REFRESH_ID_OP_GUID, + endnumeric; + + label LABEL_UPDATE3; + label LABEL_END; + + endform; + + form formid = 0x1234, // Dynamically created page, + title = STRING_TOKEN(STR_DYNAMIC_TITLE); // note formid is a variable (for readability) (UINT16) - also added Form to the line to signify the Op-Code + + label LABEL_UPDATE1; + // + // This is where we will insert dynamic created opcodes + // + label LABEL_END; + + endform; + + + form formid = 7, // Form to show the question refer to union and bit Varstore + title = STRING_TOKEN(STR_FORM7_TITLE); + + subtitle text = STRING_TOKEN(STR_NEST_BIT_EFI_VARSTORE); + + checkbox varid = MyEfiBitVar.BitsData.NestBitCheckbox, + prompt = STRING_TOKEN(STR_BIT_NEST_CHECK_BOX_PROMPT), + help = STRING_TOKEN(STR_BIT_NEST_CHECK_BOX_HELP), + flags = CHECKBOX_DEFAULT, + endcheckbox; + + oneof varid = MyEfiBitVar.BitsData.NestBitOneof, + prompt = STRING_TOKEN(STR_ONE_OF_BIT_NEST_PROMPT), + help = STRING_TOKEN(STR_ONE_OF_BIT_NEST_HELP), + option text = STRING_TOKEN(STR_BOOT_ORDER1), value = 0, flags = MANUFACTURING; + option text = STRING_TOKEN(STR_BOOT_ORDER2), value = 1, flags = DEFAULT; + endoneof; + + numeric varid = MyEfiBitVar.BitsData.NestBitNumeric, + questionid = 0x6666, + prompt = STRING_TOKEN(STR_BIT_NEST_NUMERIC_PROMPT), + help = STRING_TOKEN(STR_BIT_NEST_NUMERIC_DEFAULT_HELP), + flags = DISPLAY_UINT_HEX | INTERACTIVE, + minimum = 2, + maximum = 15, + step = 1, + endnumeric; + + oneof varid = MyEfiBitVar.BitsData.NestByteField, + prompt = STRING_TOKEN(BYTE_QUESTION_NEST_BIT_PROMPT), + help = STRING_TOKEN(BYTE_QUESTION_NEST_BIT_HELP), + option text = STRING_TOKEN(STR_BOOT_ORDER1), value = 0, flags = MANUFACTURING; + option text = STRING_TOKEN(STR_BOOT_ORDER2), value = 1, flags = DEFAULT; + endoneof; + + subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT2); + subtitle text = STRING_TOKEN(STR_BIT_EFI_VARSTORE); + + checkbox varid = MyEfiBitVar.EfiBitCheckbox, + prompt = STRING_TOKEN(STR_BIT_CHECK_BOX_PROMPT), + help = STRING_TOKEN(STR_BIT_CHECK_BOX_HELP), + flags = CHECKBOX_DEFAULT, + endcheckbox; + + grayoutif ideqval MyEfiBitVar.EfiBitGrayoutTest == 0; + numeric varid = MyEfiBitVar.EfiBitNumeric, + prompt = STRING_TOKEN(STR_BIT_NUMERIC_PROMPT), + help = STRING_TOKEN(STR_BIT_NUMERIC_HELP), + minimum = 0, + maximum = 7, + step = 0, + default = 4, defaultstore = MyStandardDefault, + default = 5, defaultstore = MyManufactureDefault, + endnumeric; + endif; + + oneof varid = MyEfiBitVar.EfiBitOneof, + questionid = 0x9999, + prompt = STRING_TOKEN(STR_ONE_OF_BIT_PROMPT), + help = STRING_TOKEN(STR_ONE_OF_BIT_HELP), + option text = STRING_TOKEN(STR_BOOT_ORDER1), value = 0x0, flags = MANUFACTURING; + option text = STRING_TOKEN(STR_BOOT_ORDER2), value = 0x1, flags = DEFAULT; + endoneof; + + subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT2); + subtitle text = STRING_TOKEN(STR_NEST_BIT_VARSTORE); + checkbox varid = MyIfrNVData.MyBitData.NestBitCheckbox, + prompt = STRING_TOKEN(STR_BIT_NEST_CHECK_BOX_PROMPT), + help = STRING_TOKEN(STR_BIT_NEST_CHECK_BOX_HELP), + flags = CHECKBOX_DEFAULT, + endcheckbox; + + oneof varid = MyIfrNVData.MyBitData.NestBitOneof, + prompt = STRING_TOKEN(STR_ONE_OF_BIT_NEST_PROMPT), + help = STRING_TOKEN(STR_ONE_OF_BIT_NEST_HELP), + option text = STRING_TOKEN(STR_BOOT_ORDER1), value = 0, flags = MANUFACTURING; + option text = STRING_TOKEN(STR_BOOT_ORDER2), value = 1, flags = DEFAULT; + endoneof; + + numeric varid = MyIfrNVData.MyBitData.NestBitNumeric, + prompt = STRING_TOKEN(STR_BIT_NEST_NUMERIC_PROMPT), + help = STRING_TOKEN(STR_BIT_NEST_NUMERIC_HELP), + minimum = 0, + maximum = 7, + step = 0, + default = 6, defaultstore = MyStandardDefault, + default = 7, defaultstore = MyManufactureDefault, + endnumeric; + + oneof varid = MyIfrNVData.MyBitData.NestByteField, + prompt = STRING_TOKEN(BYTE_QUESTION_NEST_BIT_PROMPT), + help = STRING_TOKEN(BYTE_QUESTION_NEST_BIT_HELP), + option text = STRING_TOKEN(STR_BOOT_ORDER1), value = 0, flags = MANUFACTURING; + option text = STRING_TOKEN(STR_BOOT_ORDER2), value = 1, flags = DEFAULT; + endoneof; + + subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT2); + subtitle text = STRING_TOKEN(STR_BIT_VARSTORE); + + oneof varid = MyIfrNVData.BitOneof, + prompt = STRING_TOKEN(STR_ONE_OF_BIT_PROMPT), + help = STRING_TOKEN(STR_ONE_OF_BIT_HELP), + option text = STRING_TOKEN(STR_BOOT_ORDER1), value = 0, flags = MANUFACTURING; + option text = STRING_TOKEN(STR_BOOT_ORDER2), value = 1, flags = DEFAULT; + endoneof; + + checkbox varid = MyIfrNVData.BitCheckbox, + prompt = STRING_TOKEN(STR_BIT_CHECK_BOX_PROMPT), + help = STRING_TOKEN(STR_BIT_CHECK_BOX_HELP), + flags = CHECKBOX_DEFAULT, + endcheckbox; + + numeric varid = MyIfrNVData.BitNumeric, + prompt = STRING_TOKEN(STR_BIT_NUMERIC_PROMPT), + help = STRING_TOKEN(STR_BUFFER_BIT_NUMERIC_HELP), + minimum = 0, + maximum = 20, + step = 0, + default = 16, defaultstore = MyStandardDefault, + default = 17, defaultstore = MyManufactureDefault, + endnumeric; + + subtitle text = STRING_TOKEN(STR_SUBTITLE_TEXT2); + subtitle text = STRING_TOKEN(STR_UNION_EFI_VARSTORE); + + numeric varid = MyEfiUnionVar.UnionNumeric, + prompt = STRING_TOKEN(STR_UNION_BYTE_NUMERIC_PROMPT), + help = STRING_TOKEN(STR_UNION_BYTE_NUMERIC_HELP), + minimum = 0, + maximum = 20, + step = 0, + default = 7, defaultstore = MyStandardDefault, + default = 8, defaultstore = MyManufactureDefault, + endnumeric; + + guidop + guid = DRIVER_SAMPLE_FORMSET_GUID, + datatype = MY_EFI_BITS_VARSTORE_DATA, + data.EfiBitNumeric = 1, + data.EfiBitOneof = 1, + data.EfiBitCheckbox = 1, + endguidop; + + endform; + +endformset; diff --git a/CdeEmuPkg/RedfishPkg/Documents/Media/RedfishDriverStack.svg b/CdeEmuPkg/RedfishPkg/Documents/Media/RedfishDriverStack.svg new file mode 100644 index 00000000000..0fc4a6fe766 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Documents/Media/RedfishDriverStack.svg @@ -0,0 +1,965 @@ + + + + + EDKII Redfish Driver Stack Diagrams + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VBackground-1 + + + Solid + + + + + + + + + + + Page-1 + + + + Sheet.1 + + + + Sheet.2 + RedfishLib (libredfish) + + + + RedfishLib(libredfish) + + Sheet.3 + JsonLib (jansson) + + + + JsonLib(jansson) + + Sheet.4 + EFI Redfish Discover (UEFI Driver Model) + + + + EFI Redfish Discover(UEFI Driver Model) + + Sheet.5 + EFI REST EX (UEFI Driver Model) + + + + EFI REST EX(UEFI Driver Model) + + Sheet.6 + EFI REST JSON to C Structure (DXE Driver) + + + + EFI REST JSON to C Structure(DXE Driver) + + Sheet.7 + EDKII Redfish Credential (DXE Driver) + + + + EDKII Redfish Credential(DXE Driver) + + Sheet.8 + EDKII Platform Content Coding Library + + + + EDKII Platform Content Coding Library + + Sheet.9 + EDKII Network Stacks (UEFI Driver Model) + + + + EDKII Network Stacks(UEFI Driver Model) + + Sheet.10 + EDKII Redfish Host Interface (DXE Driver) + + + + EDKII Redfish Host Interface(DXE Driver) + + Sheet.11 + SMBIOS Type 42 + + + + SMBIOS Type 42 + + Sheet.12 + RedfishPlatformConfig.efi + + + + RedfishPlatformConfig.efi + + Sheet.13 + Platform Redfish Credential Library + + + + Platform Redfish Credential Library + + Sheet.14 + Platform Redfish Host Interface Library + + + + Platform Redfish Host Interface Library + + Sheet.20 + + + + Sheet.26 + + + + Sheet.27 + + + + Sheet.34 + + + + Sheet.35 + + + + Sheet.42 + + + + Sheet.43 + + + + Sheet.44 + + + + + + + Can + Redfish Service + + Sheet.46 + + + + + + + + + + + + + Redfish Service + + + Rounded Rectangle + + + + + + + + + + + + + + + + + + + + + + Rounded Rectangle.48 + + + + + + + + + + + + + + + + + + + + + + Sheet.49 + On Network + + + + On Network + + Sheet.51 + BMC + + + + BMC + + Sheet.53 + + + + Sheet.54 + + + + Sheet.55 + + + + Sheet.56 + EDKII Redfish Foundation + + + + EDKII Redfish Foundation + + Sheet.57 + EDKII Redfish Client + + + + EDKII Redfish Client + + Rounded Rectangle.58 + SSDP over UDP + + + + + + + + + + + + + + + + + + + + + + SSDP over UDP + + + + + Can.60 + Redfish Service + + Sheet.61 + + + + + + + + + + + + + Redfish Service + + + Rounded Rectangle.62 + + + + + + + + + + + + + + + + + + + + + + Sheet.63 + BMC + + + + BMC + + Sheet.64 + Build up Redfish Host Interface + + + + Build up Redfish Host Interface + + Sheet.66 + EFI Shell Application, which builds up Redfish Host interface... + + + + EFI Shell Application, whichbuilds up Redfish Host interfacefor EDK2 emulator platform(EmulatorPkg) + + Sheet.69 + Get Authentication + + + + Get Authentication + + Sheet.71 + RedfishBiosDxe + + + + RedfishBiosDxe + + Sheet.72 + RedfishBootInfoDxe + + + + RedfishBootInfoDxe + + Sheet.73 + EDKII Redfish Feature DXE Drivers + + + + EDKII Redfish Feature DXE Drivers + + Rectangle + + + + + + + Rounded Rectangle.76 + + + + + + + + + + + + + + + + + + + + + + + + + Sheet.77 + EDKII RedfishConfigDriver (UEF Driver Model) + + + + EDKII RedfishConfigDriver(UEF Driver Model) + + Sheet.79 + + + + Rounded Rectangle.80 + + + + + + + + + + + + + + + + + + + + + + Rounded Rectangle.81 + + + + + + + + + + + + + + + + + + + + + + Sheet.90 + + + + Sheet.93 + + + + Sheet.99 + + + + Sheet.100 + + + + Wavy connector 2 + + + + + + + + + Sheet.128 + + + + Sheet.129 + + + + Sheet.130 + + + + Sheet.141 + + + + Sheet.142 + + + + Sheet.143 + + + + Sheet.144 + + + + Sheet.145 + + + + Sheet.147 + EDKII Open Source + + + + EDKII Open Source + + Sheet.148 + Other Open Source + + + + Other Open Source + + Sheet.149 + OEM EDKII Library + + + + OEM EDKII Library + + Sheet.150 + Redfish Payload Flow + + + + Redfish Payload Flow + + Sheet.151 + + + + Sheet.153 + + + + Sheet.154 + + + + Rounded Rectangle.82 + + + + + + + + + + + + + + + + + + + + + + Rounded Rectangle.83 + EDKII Redfish Config Handler Protocol + + + + + + + + + + + + + + + + + + + + + + EDKII Redfish Config Handler Protocol + + Sheet.157 + [1] + + + + [1] + + Sheet.158 + [2] + + + + [2] + + Sheet.159 + [3] + + + + [3] + + Sheet.160 + [4] + + + + [4] + + Sheet.161 + [5] + + + + [5] + + Sheet.162 + [6] + + + + [6] + + Sheet.163 + [7] + + + + [7] + + Sheet.164 + [8] + + + + [8] + + Sheet.165 + [9] + + + + [9] + + Sheet.166 + [10] + + + + [10] + + Sheet.167 + [11] + + + + [11] + + Sheet.168 + [12] + + + + [12] + + Sheet.169 + [13] + + + + [13] + + Sheet.170 + [14] + + + + [14] + + Sheet.171 + [15] + + + + [15] + + Sheet.172 + [16] + + + + [16] + + Sheet.173 + [17] + + + + [17] + + Sheet.174 + [18] + + + + [18] + + Sheet.175 + [19] + + + + [19] + + Sheet.176 + [20] + + + + [20] + + diff --git a/CdeEmuPkg/RedfishPkg/Include/IndustryStandard/RedfishHostInterface.h b/CdeEmuPkg/RedfishPkg/Include/IndustryStandard/RedfishHostInterface.h new file mode 100644 index 00000000000..44cb0499404 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Include/IndustryStandard/RedfishHostInterface.h @@ -0,0 +1,169 @@ +/** @file + This file defines the Redfish Interface Specific Data. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef REDFISH_HOST_INTERFACE_ +#define REDFISH_HOST_INTERFACE_ + +#include + +#define REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB 0x02 // We don't support this type of interface. + // Use REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2 instead. +#define REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE 0x03 // We don't support this type of interface. + // Use REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2 instead. +#define REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2 0x04 +#define REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2 0x05 + +#define REDFISH_HOST_INTERFACE_HOST_IP_ASSIGNMENT_TYPE_UNKNOWN 0x00 +#define REDFISH_HOST_INTERFACE_HOST_IP_ASSIGNMENT_TYPE_STATIC 0x01 +#define REDFISH_HOST_INTERFACE_HOST_IP_ASSIGNMENT_TYPE_DHCP 0x02 +#define REDFISH_HOST_INTERFACE_HOST_IP_ASSIGNMENT_TYPE_AUTO_CONFIGURE 0x03 +#define REDFISH_HOST_INTERFACE_HOST_IP_ASSIGNMENT_TYPE_HOST_SELECTED 0x04 + +#define REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_UNKNOWN 0x00 +#define REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4 0x01 +#define REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6 0x02 + +#pragma pack(1) +/// +/// Structure definitions of Host Interface device type 04h (USB Network Interface V2) +/// +typedef struct { + UINT8 Length; ///< Length of the structure, including Device Type + ///< and Length fields. + UINT16 IdVendor; ///< The Vendor ID of the device, as read from the + ///< idVendor field of the USB descriptor. + UINT16 IdProduct; ///< The Product ID of the device, as read from the + ///< idProduct field of the USB descriptor. + UINT8 SecialNumberStr; ///< The string number for the Serial Number of the + ///< device. The string data is read from the + ///< iSerialNumber.bDescriptorType field of the USB + ///< descriptor, and is converted from Unicode to ASCII + ///< and is NULL terminated. + UINT8 MacAddress [6]; ///< The MAC address of the PCI/PCIe network device. +} USB_INTERFACE_DEVICE_DESCRIPTOR_V2; + +// +// Structure definitions of Host Interface device type 05h (PCI/PCIE V2) +// +typedef struct { + UINT8 Length; ///< Length of the structure, including Device Type and Length fields. + UINT16 VendorId; ///< The Vendor ID of the PCI/PCIe device. + UINT16 DeviceId; ///< The Device ID of the PCI/PCIe device. + UINT16 SubsystemVendorId; ///< The Subsystem Vendor ID of the PCI/PCIe device. + UINT16 SubsystemId; ///< The Subsystem ID of the PCI/PCIe device. + UINT8 MacAddress [6]; ///< The MAC address of the PCI/PCIe network device. + UINT16 SegmemtGroupNumber; ///< The Segment Group Number of the PCI/PCIe. + UINT8 BusNumber; ///< The Bus Number of the PCI/PCIe device. + UINT8 DeviceFunctionNumber; ///< The Device/Function Number of the PCI/PCIe. +} PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2; + +/// +/// Structure definitions of Host Interface device type 80-FFh (OEM) +/// +typedef struct { + UINT32 VendorIana; ///< The IANA code for the vendor (MSB first). + UINT8 OemDefinedData[1]; ///< OEM defined data. +} OEM_DEVICE_DESCRIPTOR; + +/// +/// Define union for the Host Interface Device Descriptor +/// +typedef union { + USB_INTERFACE_DEVICE_DESCRIPTOR_V2 UsbDeviceV2; ///< Device type USB V2 device discriptor. + PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2 PciPcieDeviceV2; ///< Device type PCI/PCIe V2 device discriptor. + OEM_DEVICE_DESCRIPTOR OemDevice; ///< OEM type device discriptor. +} DEVICE_DESCRITOR; /// Device descriptor data formated based on Device Type. + +/// +/// Interface Specific Data starts at offset 06h of the SMBIOS Type 42 struct. +/// This table defines the Interface Specific data for Interface Type 40h. There +/// are 3 types of Device Descriptor3 defined , however only 1 may be used in +/// specific Tape 42 table. +/// +typedef struct { + UINT8 DeviceType; ///< The Device Type of the interface. + DEVICE_DESCRITOR DeviceDescriptor; ///< The Device descriptor. +} REDFISH_INTERFACE_DATA; + +// +// the protocol-specific data for the "Redfish Over IP" protocol +// +typedef struct { + EFI_GUID ServiceUuid; //same as Redfish Service UUID in Redfish Service Root resource + + // + // Unknown=00h, + // Static=01h, + // DHCP=02h, + // AutoConfigure=03h, + // HostSelected=04h, + // other values reserved + // + UINT8 HostIpAssignmentType; + + // + // Unknown=00h, + // Ipv4=01h, + // Ipv6=02h, + // other values reserved + // + UINT8 HostIpAddressFormat; + + // + // Used for Static and AutoConfigure. + // For IPV4, use the first 4 Bytes and zero fill the remaining bytes. + // + UINT8 HostIpAddress[16]; + + // + // Used for Static and AutoConfigure. + // For IPV4, use the first 4 Bytes and zero fill the remaining bytes. + // + UINT8 HostIpMask[16]; + + // + // Unknown=00h, + // Static=01h, + // DHCP=02h, + // AutoConfigure=03h, + // HostSelected=04h, + // other values reserved + // + UINT8 RedfishServiceIpDiscoveryType; + + // + // Unknown=00h, + // Ipv4=01h, + // Ipv6=02h, + // other values reserved + // + UINT8 RedfishServiceIpAddressFormat; + + // + // Used for Static and AutoConfigure. + // For IPV4, use the first 4 Bytes and zero fill the remaining bytes. + // + UINT8 RedfishServiceIpAddress[16]; + + // + // Used for Static and AutoConfigure. + // For IPV4, use the first 4 Bytes and zero fill the remaining bytes. + // + UINT8 RedfishServiceIpMask[16]; + + UINT16 RedfishServiceIpPort; // Used for Static and AutoConfigure. + UINT32 RedfishServiceVlanId; // Used for Static and AutoConfigure. + UINT8 RedfishServiceHostnameLength; // length of the following hostname string + UINT8 RedfishServiceHostname[1]; // hostname of Redfish Service +} REDFISH_OVER_IP_PROTOCOL_DATA; + +#pragma pack() + +#endif + diff --git a/CdeEmuPkg/RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h b/CdeEmuPkg/RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h new file mode 100644 index 00000000000..a17436bb1c2 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h @@ -0,0 +1,61 @@ +/** @file + UCS2 to UTF8 manipulation library header file. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef BASE_UCS2UTF8_LIB_H_ +#define BASE_UCS2UTF8_LIB_H_ + +/// +/// L"\u0000" +/// +#define UNICODE_FORMAT_LEN 6 +#define UNICODE_FORMAT_CHAR_LEN 2 +#define UNICODE_FORMAT_CHAR_SIZE 3 + +#define UTF8_BUFFER_FOR_UCS2_MAX_SIZE 3 + +/** + Convert a UCS2 string to a UTF8 encoded string. + + @param[in] Ucs2Str The provided UCS2 string. + @param[out] Utf8StrAddr The converted UTF8 string address. Caller + is responsible for Free this string. + + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES System runs out of resources. + @retval EFI_SUCCESS The UTF8 encoded string has been converted. + +**/ +EFI_STATUS +UCS2StrToUTF8 ( + IN CHAR16 *Ucs2Str, + OUT CHAR8 **Utf8StrAddr + ); + +/** + Convert a UTF8 encoded string to a UCS2 string. + + @param[in] Utf8Str The provided UTF8 encoded string. + @param[out] Ucs2StrAddr The converted UCS2 string address. Caller + is responsible for Free this string. + + @retval EFI_INVALID_PARAMETER The UTF8 encoded string is not valid to + convert to UCS2 string. + One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES System runs out of resources. + @retval EFI_SUCCESS The UCS2 string has been converted. + +**/ +EFI_STATUS +UTF8StrToUCS2 ( + IN CHAR8 *Utf8Str, + OUT CHAR16 **Ucs2StrAddr + ); + +#endif diff --git a/CdeEmuPkg/RedfishPkg/Include/Library/JsonLib.h b/CdeEmuPkg/RedfishPkg/Include/Library/JsonLib.h new file mode 100644 index 00000000000..74b165e00c4 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Include/Library/JsonLib.h @@ -0,0 +1,911 @@ +/** @file + APIs for JSON operations. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef JSON_LIB_H_ +#define JSON_LIB_H_ + +typedef VOID* EDKII_JSON_VALUE; +typedef VOID* EDKII_JSON_ARRAY; +typedef VOID* EDKII_JSON_OBJECT; + +/// +/// Map to json_int_t in jansson.h +/// +typedef INT64 EDKII_JSON_INT_T; // #JSON_INTEGER_IS_LONG_LONG is set to 1 + // in jansson_Config.h + +/// +/// Map to the definitions in jansson.h +/// See below URI for the JSON encoding flags reference. +/// https://jansson.readthedocs.io/en/2.13/apiref.html#encoding +/// +#define EDKII_JSON_MAX_INDENT 0x1F +#define EDKII_JSON_INDENT(n) ((n) & EDKII_JSON_MAX_INDENT) + +#define EDKII_JSON_COMPACT 0x20 +#define EDKII_JSON_ENSURE_ASCII 0x40 +#define EDKII_JSON_SORT_KEYS 0x80 +#define EDKII_JSON_PRESERVE_ORDER 0x100 +#define EDKII_JSON_ENCODE_ANY 0x200 +#define EDKII_JSON_ESCAPE_SLASH 0x400 +#define EDKII_JSON_REAL_PRECISION(n) (((n) & 0x1F) << 11) +#define EDKII_JSON_EMBED 0x10000 + +/// +/// Map to the definitions in jansson.h +/// See below URI for the JSON decoding flags reference. +/// https://jansson.readthedocs.io/en/2.13/apiref.html?highlight=json_loadb#decoding +/// +#define EDKII_JSON_REJECT_DUPLICATES 0x1 +#define EDKII_JSON_DISABLE_EOF_CHECK 0x2 +#define EDKII_JSON_DECODE_ANY 0x4 +#define EDKII_JSON_DECODE_INT_AS_REAL 0x8 +#define EDKII_JSON_ALLOW_NUL 0x10 + +#define EDKII_JSON_ARRAY_FOREACH(Array, Index, Value) \ + for(Index = 0; \ + Index < JsonArrayCount(Array) && (Value = JsonArrayGetValue(Array, Index)); \ + Index++) + +#define EDKII_JSON_OBJECT_FOREACH_SAFE(Object, N, Key, Value) \ + for (Key = JsonObjectIteratorKey(JsonObjectIterator(Object)), \ + N = JsonObjectIteratorNext(Object, JsonObjectKeyToIterator(Key)); \ + Key && (Value = JsonObjectIteratorValue(JsonObjectKeyToIterator(Key))); \ + Key = JsonObjectIteratorKey(N), \ + N = JsonObjectIteratorNext(Object, JsonObjectKeyToIterator(Key))) + +/// +/// Map to the json_error_t in jansson.h +/// +#define EDKII_JSON_ERROR_TEXT_LENGTH 160 +#define EDKII_JSON_ERROR_SOURCE_LENGTH 80 +typedef struct { + INTN Line; + INTN Column; + INTN Position; + CHAR8 Source [EDKII_JSON_ERROR_SOURCE_LENGTH]; + CHAR8 Text [EDKII_JSON_ERROR_TEXT_LENGTH]; +} EDKII_JSON_ERROR; + +/// +/// Map to the json_type in jansson.h +/// +typedef enum { + EdkiiJsonTypeObject, + EdkiiJsonTypeArray, + EdkiiJsonTypeString, + EdkiiJsonTypeInteger, + EdkiiJsonTypeReal, + EdkiiJsonTypeTrue, + EdkiiJsonTypeFalse, + EdkiiJsonTypeNull +} EDKII_JSON_TYPE; + +/** + The function is used to initialize a JSON value which contains a new JSON array, + or NULL on error. Initially, the array is empty. + + The reference count of this value will be set to 1, and caller needs to cleanup the + value by calling JsonValueFree(). + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @retval The created JSON value which contains a JSON array or NULL if intial a JSON array + is failed. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitArray ( + VOID + ); + +/** + The function is used to initialize a JSON value which contains a new JSON object, + or NULL on error. Initially, the object is empty. + + The reference count of this value will be set to 1, and caller needs to cleanup the + value by calling JsonValueFree(). + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @retval The created JSON value which contains a JSON object or NULL if intial a JSON object + is failed. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitObject ( + VOID + ); + +/** + The function is used to initialize a JSON value which contains a new JSON string, + or NULL on error. + + The input string must be NULL terminated Ascii format, non-Ascii characters will + be processed as an error. Unicode characters can also be represented by Ascii string + as the format: \u + 4 hexadecimal digits, like \u3E5A, or \u003F. + + The reference count of this value will be set to 1, and caller needs to cleanup the + value by calling JsonValueFree(). + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @param[in] String The Ascii string to initialize to JSON value + + @retval The created JSON value which contains a JSON string or NULL. Select a + Getter API for a specific encoding format. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitAsciiString ( + IN CONST CHAR8 *String + ); + +/** + The function is used to initialize a JSON value which contains a new JSON string, + or NULL on error. + + The input must be a NULL terminated UCS2 format Unicode string. + + The reference count of this value will be set to 1, and caller needs to cleanup the + value by calling JsonValueFree(). + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @param[in] String The Unicode string to initialize to JSON value + + @retval The created JSON value which contains a JSON string or NULL. Select a + Getter API for a specific encoding format. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitUnicodeString ( + IN CHAR16 *String + ); + +/** + The function is used to initialize a JSON value which contains a new JSON integer, + or NULL on error. + + The reference count of this value will be set to 1, and caller needs to cleanup the + value by calling JsonValueFree(). + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @param[in] Value The integer to initialize to JSON value + + @retval The created JSON value which contains a JSON integer or NULL. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitInteger ( + IN INT64 Value + ); + +/** + The function is used to initialize a JSON value which contains a new JSON boolean, + or NULL on error. + + Boolean JSON value is kept as static value, and no need to do any cleanup work. + + @param[in] Value The boolean value to initialize. + + @retval The created JSON value which contains a JSON boolean or NULL. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitBoolean ( + IN BOOLEAN Value + ); + +/** + The function is used to initialize a JSON value which contains a new JSON NULL, + or NULL on error. + + NULL JSON value is kept as static value, and no need to do any cleanup work. + + @retval The created NULL JSON value. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitNull ( + VOID + ); + +/** + The function is used to initialize a JSON value which contains a TRUE JSON value, + or NULL on error. + + NULL JSON value is kept as static value, and no need to do any cleanup work. + + @retval The created JSON TRUE value. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitTrue ( + VOID + ); + +/** + The function is used to initialize a JSON value which contains a FALSE JSON value, + or NULL on error. + + NULL JSON value is kept as static value, and no need to do any cleanup work. + + @retval The created JSON FALSE value. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitFalse ( + VOID + ); + +/** + The function is used to decrease the reference count of a JSON value by one, and once + this reference count drops to zero, the value is destroyed and it can no longer be used. + If this destroyed value is object type or array type, reference counts for all containing + JSON values will be decreased by 1. Boolean JSON value and NULL JSON value won't be destroyed + since they are static values kept in memory. + + Reference Count Strategy: BaseJsonLib uses this strategy to track whether a value is still + in use or not. When a value is created, it's reference count is set to 1. If a reference to a + value is kept for use, its reference count is incremented, and when the value is no longer + needed, the reference count is decremented. When the reference count drops to zero, there are + no references left, and the value can be destroyed. + + The given JSON value maybe NULL and not causing any problem. Just output the debug message + to inform caller the NULL value is passed in. + + @param[in] Json The JSON value to be freed. json_decref may return without any + changes if Json is NULL. + +**/ +VOID +EFIAPI +JsonValueFree ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to create a fresh copy of a JSON value, and all child values are deep + copied in a recursive fashion. It should be called when this JSON value might be modified + in later use, but the original still wants to be used in somewhere else. + + Reference counts of the returned root JSON value and all child values will be set to 1, and + caller needs to cleanup the root value by calling JsonValueFree(). + + * Note: Since this function performs a copy from bottom to up, too many calls may cause some + performance issues, user should avoid unnecessary calls to this function unless it is really + needed. + + @param[in] Json The JSON value to be cloned. + + @retval Return the cloned JSON value, or NULL on error. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueClone ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to return if the provided JSON value contains a JSON array. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a JSON array. + @retval FALSE The JSON value doesn't contain a JSON array. + +**/ +BOOLEAN +EFIAPI +JsonValueIsArray ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to return if the provided JSON value contains a JSON object. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a JSON object. + @retval FALSE The JSON value doesn't contain a JSON object. + +**/ +BOOLEAN +EFIAPI +JsonValueIsObject ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to return if the provided JSON Value contains a string, Ascii or + Unicode format is not differentiated. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a JSON string. + @retval FALSE The JSON value doesn't contain a JSON string. + +**/ +BOOLEAN +EFIAPI +JsonValueIsString ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to return if the provided JSON value contains a JSON integer. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value is contains JSON integer. + @retval FALSE The JSON value doesn't contain a JSON integer. + +**/ +BOOLEAN +EFIAPI +JsonValueIsInteger ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to return if the provided JSON value contains a JSON number. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value is contains JSON number. + @retval FALSE The JSON value doesn't contain a JSON number. + +**/ +BOOLEAN +EFIAPI +JsonValueIsNumber ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to return if the provided JSON value contains a JSON boolean. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a JSON boolean. + @retval FALSE The JSON value doesn't contain a JSON boolean. + +**/ +BOOLEAN +EFIAPI +JsonValueIsBoolean ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to return if the provided JSON value contains a TRUE value. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a TRUE value. + @retval FALSE The JSON value doesn't contain a TRUE value. + +**/ +BOOLEAN +EFIAPI +JsonValueIsTrue ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to return if the provided JSON value contains a FALSE value. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a FALSE value. + @retval FALSE The JSON value doesn't contain a FALSE value. + +**/ +BOOLEAN +EFIAPI +JsonValueIsFalse ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to return if the provided JSON value contains a JSON NULL. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a JSON NULL. + @retval FALSE The JSON value doesn't contain a JSON NULL. + +**/ +BOOLEAN +EFIAPI +JsonValueIsNull ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to retrieve the associated array in an array type JSON value. + + Any changes to the returned array will impact the original JSON value. + + @param[in] Json The provided JSON value. + + @retval Return the associated array in JSON value or NULL. + +**/ +EDKII_JSON_ARRAY +EFIAPI +JsonValueGetArray ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to retrieve the associated object in an object type JSON value. + + Any changes to the returned object will impact the original JSON value. + + @param[in] Json The provided JSON value. + + @retval Return the associated object in JSON value or NULL. + +**/ +EDKII_JSON_OBJECT +EFIAPI +JsonValueGetObject ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to retrieve the associated Ascii string in a string type JSON value. + + Any changes to the returned string will impact the original JSON value. + + @param[in] Json The provided JSON value. + + @retval Return the associated Ascii string in JSON value or NULL. + +**/ +CONST CHAR8 * +EFIAPI +JsonValueGetAsciiString ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to retrieve the associated Unicode string in a string type JSON value. + + Caller can do any changes to the returned string without any impact to the original JSON + value, and caller needs to free the returned string using FreePool(). + + @param[in] Json The provided JSON value. + + @retval Return the associated Unicode string in JSON value or NULL. + +**/ +CHAR16* +EFIAPI +JsonValueGetUnicodeString ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to retrieve the associated integer in a integer type JSON value. + + The input JSON value should not be NULL or contain no JSON Integer, otherwise it will + ASSERT() and return 0. + + @param[in] Json The provided JSON value. + + @retval Return the associated Integer in JSON value. + +**/ +INT64 +EFIAPI +JsonValueGetInteger ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to retrieve the associated boolean in a boolean type JSON value. + + The input JSON value should not be NULL or contain no JSON boolean, otherwise it will + ASSERT() and return FALSE. + + @param[in] Json The provided JSON value. + + @retval Return the associated value of JSON boolean. + +**/ +BOOLEAN +EFIAPI +JsonValueGetBoolean ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to retrieve the associated string in a string type JSON value. + + Any changes to the returned string will impact the original JSON value. + + @param[in] Json The provided JSON value. + + @retval Return the associated Ascii string in JSON value or NULL on errors. + +**/ +CONST CHAR8* +EFIAPI +JsonValueGetString ( + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to get the number of elements in a JSON object, or 0 if it is NULL or + not a JSON object. + + @param[in] JsonObject The provided JSON object. + + @retval Return the number of elements in this JSON object or 0. + +**/ +UINTN +EFIAPI +JsonObjectSize ( + IN EDKII_JSON_OBJECT JsonObject + ); + +/** + The function is used to enumerate all keys in a JSON object. + + Caller should be responsible to free the returned key array reference using + FreePool(). But contained keys are read only and must not be modified or freed. + + @param[in] JsonObj The provided JSON object for enumeration. + @param[out] KeyCount The count of keys in this JSON object. + + @retval Return an array of the enumerated keys in this JSON object or NULL if + JsonObj is not an JSON object, key count is zero or on other errors. + +**/ +CHAR8** +JsonObjectGetKeys ( + IN EDKII_JSON_OBJECT JsonObj, + OUT UINTN *KeyCount + ); + +/** + The function is used to get a JSON value corresponding to the input key from a JSON object. + + It only returns a reference to this value and any changes on this value will impact the + original JSON object. If that is not expected, please call JsonValueClone() to clone it to + use. + + Input key must be a valid NULL terminated UTF8 encoded string. NULL will be returned when + Key-Value is not found in this JSON object. + + @param[in] JsonObj The provided JSON object. + @param[in] Key The key of the JSON value to be retrieved. + + @retval Return the corresponding JSON value to key, or NULL on error. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonObjectGetValue ( + IN CONST EDKII_JSON_OBJECT JsonObj, + IN CONST CHAR8 *Key + ); + +/** + The function is used to set a JSON value corresponding to the input key from a JSON object, + and the reference count of this value will be increased by 1. + + Input key must be a valid NULL terminated UTF8 encoded string. If there already is a value for + this key, this key will be assigned to the new JSON value. The old JSON value will be removed + from this object and thus its' reference count will be decreased by 1. + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @param[in] JsonObj The provided JSON object. + @param[in] Key The key of the JSON value to be set. + @param[in] Json The JSON value to set to this JSON object mapped by key. + + @retval EFI_ABORTED Some error occur and operation aborted. + @retval EFI_SUCCESS The JSON value has been set to this JSON object. + +**/ +EFI_STATUS +EFIAPI +JsonObjectSetValue ( + IN EDKII_JSON_OBJECT JsonObj, + IN CONST CHAR8 *Key, + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to get the number of elements in a JSON array. Returns or 0 if JsonArray + is NULL or not a JSON array. + + @param[in] JsonArray The provided JSON array. + + @retval Return the number of elements in this JSON array or 0. + +**/ +UINTN +EFIAPI +JsonArrayCount ( + IN EDKII_JSON_ARRAY JsonArray + ); + +/** + The function is used to return the JSON value in the array at position index. The valid range + for this index is from 0 to the return value of JsonArrayCount() minus 1. + + It only returns a reference to this value and any changes on this value will impact the + original JSON object. If that is not expected, please call JsonValueClone() to clone it to + use. + + If this array is NULL or not a JSON array, or if index is out of range, NULL will be returned. + + @param[in] JsonArray The provided JSON Array. + + @retval Return the JSON value located in the Index position or + NULL if JsonArray is not an array or no items in the array. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonArrayGetValue ( + IN EDKII_JSON_ARRAY JsonArray, + IN UINTN Index + ); + +/** + The function is used to append a JSON value to the end of the JSON array, and grow the size of + array by 1. The reference count of this value will be increased by 1. + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @param[in] JsonArray The provided JSON object. + @param[in] Json The JSON value to append. + + @retval EFI_ABORTED Some error occur and operation aborted. + @retval EFI_SUCCESS JSON value has been appended to the end of the JSON array. + +**/ +EFI_STATUS +EFIAPI +JsonArrayAppendValue ( + IN EDKII_JSON_ARRAY JsonArray, + IN EDKII_JSON_VALUE Json + ); + +/** + The function is used to remove a JSON value at position index, shifting the elements after index + one position towards the start of the array. The reference count of this value will be decreased + by 1. + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @param[in] JsonArray The provided JSON array. + @param[in] Index The Index position before removement. + + @retval EFI_ABORTED Some error occur and operation aborted. + @retval EFI_SUCCESS The JSON array has been removed at position index. + +**/ +EFI_STATUS +EFIAPI +JsonArrayRemoveValue ( + IN EDKII_JSON_ARRAY JsonArray, + IN UINTN Index + ); + +/** + Dump JSON to a buffer. + + @param[in] JsonValue The provided JSON value. + @param[in] Flags The Index position before removement. The value + could be the combination of below flags. + - EDKII_JSON_INDENT(n) + - EDKII_JSON_COMPACT + - EDKII_JSON_ENSURE_ASCII + - EDKII_JSON_SORT_KEYS + - EDKII_JSON_PRESERVE_ORDER + - EDKII_JSON_ENCODE_ANY + - EDKII_JSON_ESCAPE_SLASH + - EDKII_JSON_REAL_PRECISION(n) + - EDKII_JSON_EMBED + See below URI for the JSON encoding flags reference. + https://jansson.readthedocs.io/en/2.13/apiref.html#encoding + + @retval CHAR8 * Dump fail if NULL returned, otherwise the buffer + contain JSON paylaod in ASCII string. The return + value must be freed by the caller FreePool(). +**/ +CHAR8 * +EFIAPI +JsonDumpString ( + IN EDKII_JSON_VALUE JsonValue, + IN UINTN Flags + ); + +/** + Convert a string to JSON object. + The function is used to convert a NULL terminated CHAR8 string to a JSON + value. Only object and array represented strings can be converted successfully, + since they are the only valid root values of a JSON text for UEFI usage. + + Real number and number with exponent part are not supportted by UEFI. + + Caller needs to cleanup the root value by calling JsonValueFree(). + + @param[in] String The NULL terminated CHAR8 string to convert. + @param[in] Flags Flags for loading JSON string. + @param[in] Error Returned error status. + + @retval Array JSON value or object JSON value, or NULL when any error occurs. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonLoadString ( + IN CONST CHAR8* String, + IN UINT64 Flags, + IN EDKII_JSON_ERROR *Error + ); + +/** + Load JSON from a buffer. + + @param[in] Buffer Bufffer to the JSON payload + @param[in] BufferLen Length of the buffer + @param[in] Flags Flag of loading JSON buffer, the value + could be the combination of below flags. + - EDKII_JSON_REJECT_DUPLICATES + - EDKII_JSON_DISABLE_EOF_CHECK + - EDKII_JSON_DECODE_ANY + - EDKII_JSON_DECODE_INT_AS_REAL + - EDKII_JSON_ALLOW_NUL + See below URI for the JSON encoding flags reference. + https://jansson.readthedocs.io/en/2.13/apiref.html?highlight=json_loadb#decoding + + @param[in,out] Error Pointer EDKII_JSON_ERROR structure + + @retval EDKII_JSON_VALUE NULL means fail to load JSON payload. +**/ +EDKII_JSON_VALUE +EFIAPI +JsonLoadBuffer ( + IN CONST CHAR8 *Buffer, + IN UINTN BufferLen, + IN UINTN Flags, + IN OUT EDKII_JSON_ERROR *Error + ); + +/** + The reference count is used to track whether a value is still in use or not. + When a value is created, it's reference count is set to 1. + when the value is no longer needed, the reference count is decremented. + When the reference count drops to zero, there are no references left and the + value can be destroyed. + + This funciton decrement the reference count of EDKII_JSON_VALUE. As soon as + a call to json_decref() drops the reference count to zero, the value is + destroyed and it can no longer be used. + + @param[in] JsonValue JSON value +**/ +VOID +EFIAPI +JsonDecreaseReference ( + IN EDKII_JSON_VALUE JsonValue + ); + +/** + The reference count is used to track whether a value is still in use or not. + When a value is created, it's reference count is set to 1. + If a reference to a value is kept (e.g. a value is stored somewhere for later use), + its reference count is incremented. + + This function increment the reference count of json if it's not NULL. + Returns EDKII_JSON_VALUE. + + @param[in] JsonValue JSON value + @retval EDKII_JSON_VALUE of itself +**/ +EDKII_JSON_VALUE +EFIAPI +JsonIncreaseReference ( + IN EDKII_JSON_VALUE JsonValue + ); +/** + Returns an opaque iterator which can be used to iterate over all key-value pairs + in object, or NULL if object is empty + + @param[in] JsonValue JSON value +**/ +VOID * +EFIAPI +JsonObjectIterator ( + IN EDKII_JSON_VALUE JsonValue + ); + +/** + Extract the associated value from iterator. + + @param[in] Iterator Iterator pointer +**/ +EDKII_JSON_VALUE +EFIAPI +JsonObjectIteratorValue ( + IN VOID *Iterator + ); + +/** + Returns an iterator pointing to the next key-value pair in object after iter, + or NULL if the whole object has been iterated through. + + @param[in] JsonValue JSON value + @param[in] Iterator Iterator pointer + @retval Iterator pointer +**/ +VOID * +EFIAPI +JsonObjectIteratorNext ( + IN EDKII_JSON_VALUE JsonValue, + IN VOID *Iterator + ); + +/** + Returns the key of iterator pointing + + @param[in] Iterator Iterator pointer + @retval Key +**/ +CHAR8 * +EFIAPI +JsonObjectIteratorKey ( + IN VOID *Iterator +); + +/** + Returns the pointer of iterator by key. + + @param[in] Key The key of interator pointer. + @retval Pointer to interator +**/ +VOID * +EFIAPI +JsonObjectKeyToIterator ( + IN CHAR8 *Key +); + +/** + Returns the json type of this json value + + @param[in] JsonValue JSON value + @retval JSON type returned +**/ +EDKII_JSON_TYPE +EFIAPI +JsonGetType( + IN EDKII_JSON_VALUE JsonValue + ); +#endif diff --git a/CdeEmuPkg/RedfishPkg/Include/Library/RedfishContentCodingLib.h b/CdeEmuPkg/RedfishPkg/Include/Library/RedfishContentCodingLib.h new file mode 100644 index 00000000000..72d6799b004 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Include/Library/RedfishContentCodingLib.h @@ -0,0 +1,78 @@ +/** @file + Definitinos of RedfishContentCodingLib. + + (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef REDFISH_CONTENT_CODING_LIB_H_ +#define REDFISH_CONTENT_CODING_LIB_H_ + +/** + This is the function to encode the content use the + algorithm indicated in ContentEncodedValue. The naming of + ContentEncodedValue is follow HTTP spec or could be a + platform-specific value. + + @param[in] ContentEncodedValue HTTP conent encoded value. + The value could be one of below + or any which is platform-specific. + - HTTP_CONTENT_ENCODING_IDENTITY "identity" + - HTTP_CONTENT_ENCODING_GZIP "gzip" + - HTTP_CONTENT_ENCODING_COMPRESS "compress" + - HTTP_CONTENT_ENCODING_DEFLATE "deflate" + - HTTP_CONTENT_ENCODING_BROTLI "br" + @param[in] OriginalContent Original content. + @param[in] OriginalContentLength The length of original content. + @param[out] EncodedContentPointer Pointer to receive the encoded content pointer. + @param[out] EncodedContentLength Length of encoded content. + + @retval EFI_SUCCESS Content is encoded successfully. + @retval EFI_UNSUPPORTED No supported encoding funciton, + @retval EFI_INVALID_PARAMETER One of the given parameter is invalid. + +**/ + +EFI_STATUS +RedfishContentEncode ( + IN CHAR8 *ContentEncodedValue, + IN CHAR8 *OriginalContent, + IN UINTN OriginalContentLength, + OUT VOID **EncodedContentPointer, + OUT UINTN *EncodedLength + ); + +/** + This is the function to decode the content use the + algorithm indicated in ContentEncodedValue. The naming of + ContentEncodedValue is follow HTTP spec or could be a + platform-specific value. + + @param[in] ContentDecodedValue HTTP conent decoded value. + The value could be one of below + or any which is platform-specific. + - HTTP_CONTENT_ENCODING_IDENTITY "identity" + - HTTP_CONTENT_ENCODING_GZIP "gzip" + - HTTP_CONTENT_ENCODING_COMPRESS "compress" + - HTTP_CONTENT_ENCODING_DEFLATE "deflate" + - HTTP_CONTENT_ENCODING_BROTLI "br" + @param[in] ContentPointer Original content. + @param[in] ContentLength The length of original content. + @param[out] DecodedContentPointer Pointer to receive decoded content pointer. + @param[out] DecodedContentLength Length of decoded content. + + @retval EFI_SUCCESS Content is decoded successfully. + @retval EFI_UNSUPPORTED No supported decoding funciton, + @retval EFI_INVALID_PARAMETER One of the given parameter is invalid. + +**/ +EFI_STATUS +RedfishContentDecode ( + IN CHAR8 *ContentEncodedValue, + IN VOID *ContentPointer, + IN UINTN ContentLength, + OUT VOID **DecodedContentPointer, + OUT UINTN *DecodedLength + ); +#endif diff --git a/CdeEmuPkg/RedfishPkg/Include/Library/RedfishCredentialLib.h b/CdeEmuPkg/RedfishPkg/Include/Library/RedfishCredentialLib.h new file mode 100644 index 00000000000..f4c788f91e0 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Include/Library/RedfishCredentialLib.h @@ -0,0 +1,91 @@ +/** @file + Definitinos of RedfishHostInterfaceDxe driver. + + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef REDFISH_CREDENTIAL_LIB_H_ +#define REDFISH_CREDENTIAL_LIB_H_ + +#include + +/** + Notification of Exit Boot Service. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL. +**/ +VOID +EFIAPI +LibCredentialExitBootServicesNotify ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This +); + +/** + Notification of End of DXe. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL. +**/ +VOID +EFIAPI +LibCredentialEndOfDxeNotify ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This +); + +/** + Retrieve platform's Redfish authentication information. + + This functions returns the Redfish authentication method together with the user Id and + password. + - For AuthMethodNone, the UserId and Password could be used for HTTP header authentication + as defined by RFC7235. + - For AuthMethodRedfishSession, the UserId and Password could be used for Redfish + session login as defined by Redfish API specification (DSP0266). + + Callers are responsible for and freeing the returned string storage. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + @param[out] AuthMethod Type of Redfish authentication method. + @param[out] UserId The pointer to store the returned UserId string. + @param[out] Password The pointer to store the returned Password string. + + @retval EFI_SUCCESS Get the authentication information successfully. + @retval EFI_ACCESS_DENIED SecureBoot is disabled after EndOfDxe. + @retval EFI_INVALID_PARAMETER This or AuthMethod or UserId or Password is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough memory resources. + @retval EFI_UNSUPPORTED Unsupported authentication method is found. + +**/ +EFI_STATUS +EFIAPI +LibCredentialGetAuthInfo ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, + OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod, + OUT CHAR8 **UserId, + OUT CHAR8 **Password +); + +/** + Notify the Redfish service provide to stop provide configuration service to this platform. + + This function should be called when the platfrom is about to leave the safe environment. + It will notify the Redfish service provider to abort all logined session, and prohibit + further login with original auth info. GetAuthInfo() will return EFI_UNSUPPORTED once this + function is returned. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + @param[in] ServiceStopType Reason of stopping Redfish service. + + @retval EFI_SUCCESS Service has been stoped successfully. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +LibStopRedfishService ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, + IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType +); +#endif diff --git a/CdeEmuPkg/RedfishPkg/Include/Library/RedfishCrtLib.h b/CdeEmuPkg/RedfishPkg/Include/Library/RedfishCrtLib.h new file mode 100644 index 00000000000..654d0ca978d --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Include/Library/RedfishCrtLib.h @@ -0,0 +1,242 @@ +/** @file + Redfish CRT wrapper functions. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef REDFISH_CRT_LIB_H_ +#define REDFISH_CRT_LIB_H_ + +#include +#include +#include +#include + +#define MAX_STRING_SIZE 0x10000000 + +// Minimum value for an object of type long long int. +#define LLONG_MIN MIN_INT64 + +// Maximum value for an object of type long long int. +#define LLONG_MAX MAX_INT64 + +// We dont support double on edk2 +#define HUGE_VAL 0 + +#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) || defined(MDE_CPU_RISCV64) +// +// With GCC we would normally use SIXTY_FOUR_BIT_LONG, but MSVC needs +// SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is +// 64-bit. Since using 'long long' works fine on GCC too, just do that. +// +#define SIXTY_FOUR_BIT +#elif defined(MDE_CPU_IA32) || defined(MDE_CPU_ARM) || defined(MDE_CPU_EBC) +#define THIRTY_TWO_BIT +#endif + +// +// Map all va_xxxx elements to VA_xxx defined in MdePkg/Include/Base.h +// +#if !defined(__CC_ARM) // if va_list is not already defined +#define va_list VA_LIST +#define va_arg VA_ARG +#define va_start VA_START +#define va_end VA_END +#else // __CC_ARM +#define va_start(Marker, Parameter) __va_start(Marker, Parameter) +#define va_arg(Marker, TYPE) __va_arg(Marker, TYPE) +#define va_end(Marker) ((void)0) +#endif + +// +// Definitions for global constants used by CRT library routines +// +#define INT_MAX MAX_INT32 /* Maximum (signed) int value */ +#define LONG_MAX 0X7FFFFFFFL /* max value for a long */ +#define LONG_MIN (-LONG_MAX-1) /* min value for a long */ +#define ULONG_MAX 0xFFFFFFFF /* Maximum unsigned long value */ +#define CHAR_BIT 8 /* Number of bits in a char */ + +// Maximum value for an object of type unsigned long long int. +#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL // 2^64 - 1 +// Maximum value for an object of type unsigned char. +#define UCHAR_MAX 255 // 2^8 - 1 + +// +// Basic types mapping +// +typedef UINTN size_t; +typedef INTN ssize_t; +typedef INT32 time_t; +typedef UINT8 __uint8_t; +typedef UINT8 sa_family_t; +typedef UINT32 uid_t; +typedef UINT32 gid_t; +typedef INT32 int32_t; +typedef UINT32 uint32_t; +typedef UINT16 uint16_t; +typedef UINT8 uint8_t; +typedef enum {false, true} bool; + +// +// File operations are not required for EFI building, +// so FILE is mapped to VOID * to pass build +// +typedef VOID *FILE; + +/** + This is the Redfish version of CRT snprintf function, this function replaces "%s" to + "%a" before invoking AsciiSPrint(). That is becasue "%s" is unicode base on edk2 + environment however "%s" is ascii code base on snprintf(). + See definitions of AsciiSPrint() for the details. + + @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated + ASCII string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString A Null-terminated ASCII format string. + @param ... Variable argument list whose contents are accessed based on the + format string specified by FormatString. + + @return The number of ASCII characters in the produced output buffer not including the + Null-terminator. Zero means no string is produced or the error happens. + +**/ +UINTN +EFIAPI +RedfishAsciiSPrint ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + ... + ); + +/** + This is the Redfish version of CRT vsnprintf function, this function replaces "%s" to + "%a" before invoking AsciiVSPrint(). That is because "%s" is unicode base on edk2 + environment however "%s" is ascii code base on vsnprintf(). + See definitions of AsciiVSPrint() for the details. + + @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated + ASCII string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString A Null-terminated ASCII format string. + @param Marker VA_LIST marker for the variable argument list. + + @return The number of ASCII characters in the produced output buffer not including the + Null-terminator. + +**/ +UINTN +EFIAPI +RedfishAsciiVSPrint ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + IN VA_LIST Marker + ); + +// +// Global variables +// +extern int errno; +extern FILE *stderr; + +// +// Function prototypes of CRT Library routines +// +void *malloc (size_t); +void *realloc (void *, size_t); +void *calloc (size_t Num, size_t Size); +void free (void *); +void *memset (void *, int, size_t); +int memcmp (const void *, const void *, size_t); +int isdigit (int); +int isspace (int); +int tolower (int); +int isupper (int); +int isxdigit (int); +int isalnum (int); +void *memcpy (void *, const void *, size_t); +void *memset (void *, int, size_t); +void *memchr (const void *, int, size_t); +int memcmp (const void *, const void *, size_t); +void *memmove (void *, const void *, size_t); +int strcmp (const char *, const char *); +int strncmp (const char *, const char *, size_t); +char *strcpy (char *, const char *); +size_t strlen (const char *); +char *strcat (char *, const char *); +char *strchr (const char *, int); +int strcasecmp (const char *, const char *); +int strncasecmp (const char *, const char *, size_t); +char *strncpy (char *, size_t, const char *, size_t); +int strncmp (const char *, const char *, size_t); +char *strrchr (const char *, int); +unsigned long strtoul (const char *, char **, int); +char * strstr (const char *s1 , const char *s2); +long strtol (const char *, char **, int); +char *strerror (int); +size_t strspn (const char *, const char *); +char * strdup (const char *str); +char * strpbrk (const char *s1, const char *s2); +unsigned long long strtoull(const char * nptr, char ** endptr, int base); +long long strtoll (const char * nptr, char ** endptr, int base); +long strtol (const char * nptr, char ** endptr, int base); +double strtod (const char * __restrict nptr, char ** __restrict endptr); +size_t strcspn (const char *, const char *); +int printf (const char *, ...); +int sscanf (const char *, const char *, ...); +FILE *fopen (const char *, const char *); +size_t fread (void *, size_t, size_t, FILE *); +size_t fwrite (const void *, size_t, size_t, FILE *); +int fclose (FILE *); +int fprintf (FILE *, const char *, ...); +int fgetc (FILE * _File); +uid_t getuid (void); +uid_t geteuid (void); +gid_t getgid (void); +gid_t getegid (void); +void qsort (void *, size_t, size_t, int (*)(const void *, const void *)); +char *getenv (const char *); +#if defined(__GNUC__) && (__GNUC__ >= 2) +void abort (void) __attribute__((__noreturn__)); +#else +void abort (void); +#endif +int toupper (int); +int Digit2Val (int); +time_t time (time_t *); + +// +// Macros that directly map functions to BaseLib, BaseMemoryLib, and DebugLib functions +// +#define strcmp AsciiStrCmp +#define memcpy(dest,source,count) CopyMem(dest,source,(UINTN)(count)) +#define memset(dest,ch,count) SetMem(dest,(UINTN)(count),(UINT8)(ch)) +#define memchr(buf,ch,count) ScanMem8(buf,(UINTN)(count),(UINT8)ch) +#define memcmp(buf1,buf2,count) (int)(CompareMem(buf1,buf2,(UINTN)(count))) +#define memmove(dest,source,count) CopyMem(dest,source,(UINTN)(count)) +#define strlen(str) (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE)) +#define strcpy(strDest,strSource) AsciiStrCpyS(strDest,(strlen(strSource)+1),strSource) +#define strncpy(strDest,strSource,count) AsciiStrnCpyS(strDest,(UINTN)count,strSource,(UINTN)count) +#define strncpys(strDest, DestLen, strSource,count) AsciiStrnCpyS(strDest,DestLen,strSource,(UINTN)count) +#define strcat(strDest,strSource) AsciiStrCatS(strDest,(strlen(strSource)+strlen(strDest)+1),strSource) +#define strchr(str,ch) ScanMem8((VOID *)(str),AsciiStrSize(str),(UINT8)ch) +#define strcasecmp(str1,str2) (int)AsciiStriCmp(str1,str2) +#define strstr(s1,s2) AsciiStrStr(s1,s2) +#define snprintf(buf,len,...) RedfishAsciiSPrint(buf,len,__VA_ARGS__) +#define vsnprintf(buf,len,format,marker) RedfishAsciiVSPrint((buf),(len),(format),(marker)) +#define assert(expression) ASSERT(expression) +#define offsetof(type,member) OFFSET_OF(type,member) + +#define EOF (-1) + +extern int errno; + +#define ERANGE 34 /* 34 Result too large */ + +#endif diff --git a/CdeEmuPkg/RedfishPkg/Include/Library/RedfishHostInterfaceLib.h b/CdeEmuPkg/RedfishPkg/Include/Library/RedfishHostInterfaceLib.h new file mode 100644 index 00000000000..896febb6deb --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Include/Library/RedfishHostInterfaceLib.h @@ -0,0 +1,52 @@ +/** @file + Definitinos of RedfishHostInterfaceDxe driver. + + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef REDFISH_HOST_INTERFACE_LIB_H_ +#define REDFISH_HOST_INTERFACE_LIB_H_ + +#include +#include +#include + +#include + +/** + Get platform Redfish host interface device descriptor. + + @param[in] DeviceType Pointer to retrieve device type. + @param[out] DeviceDescriptor Pointer to retrieve REDFISH_INTERFACE_DATA, caller has to free + this memory using FreePool(). + @retval EFI_SUCCESS Device descriptor is returned successfully in DeviceDescriptor. + @retval EFI_NOT_FOUND No Redfish host interface descriptor provided on this platform. + @retval Others Fail to get device descriptor. +**/ +EFI_STATUS +RedfishPlatformHostInterfaceDeviceDescriptor ( + IN UINT8 *DeviceType, + OUT REDFISH_INTERFACE_DATA **DeviceDescriptor +); +/** + Get platform Redfish host interface protocol data. + Caller should pass NULL in ProtocolRecord to retrive the first protocol record. + Then continuously pass previous ProtocolRecord for retrieving the next ProtocolRecord. + + @param[in, out] ProtocolRecord Pointer to retrieve the first or the next protocol record. + caller has to free the new protocol record returned from + this function using FreePool(). + param[in] IndexOfProtocolData The index of protocol data. + + @retval EFI_SUCCESS Protocol records are all returned. + @retval EFI_NOT_FOUND No more protocol records. + @retval Others Fail to get protocol records. +**/ +EFI_STATUS +RedfishPlatformHostInterfaceProtocolData ( + IN OUT MC_HOST_INTERFACE_PROTOCOL_RECORD **ProtocolRecord, + IN UINT8 IndexOfProtocolData +); +#endif diff --git a/CdeEmuPkg/RedfishPkg/Include/Library/RestExLib.h b/CdeEmuPkg/RedfishPkg/Include/Library/RestExLib.h new file mode 100644 index 00000000000..38858145ec8 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Include/Library/RestExLib.h @@ -0,0 +1,42 @@ +/** @file + This library provides help functions for REST EX Protocol. + + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef REST_EX_LIB_H_ +#define REST_EX_LIB_H_ + +#include + +/// +/// Library class public functions +/// + +/** + This function allows the caller to create child handle for specific + REST server. + + @param[in] Image The image handle used to open service. + @param[in] AccessMode Access mode of REST server. + @param[in] ConfigType Underlying configuration to communicate with REST server. + @param[in] ServiceType REST service type. + @param[out] ChildInstanceHandle The handle to receive the create child. + + @retval EFI_SUCCESS Can't create the corresponding REST EX child instance. + @retval EFI_INVALID_PARAMETERS Any of input parameters is improper. + +**/ +EFI_STATUS +RestExLibCreateChild ( + IN EFI_HANDLE Image, + IN EFI_REST_EX_SERVICE_ACCESS_MODE AccessMode, + IN EFI_REST_EX_CONFIG_TYPE ConfigType, + IN EFI_REST_EX_SERVICE_TYPE ServiceType, + OUT EFI_HANDLE *ChildInstanceHandle +); + +#endif diff --git a/CdeEmuPkg/RedfishPkg/Include/Pcd/RestExServiceDevicePath.h b/CdeEmuPkg/RedfishPkg/Include/Pcd/RestExServiceDevicePath.h new file mode 100644 index 00000000000..1cfc9fd204a --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Include/Pcd/RestExServiceDevicePath.h @@ -0,0 +1,38 @@ +/** @file + This library defines the UEFI device path data of network device for REST + service to decide which should be used as the Redfish host interface. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef REST_EX_SERVICE_DEVICE_PATH_H_ +#define REST_EX_SERVICE_DEVICE_PATH_H_ + +#include + +typedef enum { + DEVICE_PATH_MATCH_MAC_NODE = 1, + DEVICE_PATH_MATCH_PCI_NODE = 2, + DEVICE_PATH_MATCH_MODE_MAX +} DEVICE_PATH_MATCH_MODE; + +typedef struct { + UINT32 DevicePathMatchMode; + UINT32 DevicePathNum; + // + // Example: + // {DEVICE_PATH("PciRoot(0)/Pci(0,0)/MAC(005056C00002,0x1)")} + // DevicePath will be parsed as below: + // {0x02,0x01,0x0c,0x00,0xd0,0x41,0x03,0x0a,0x00,0x00,0x00,0x00, + // 0x01,0x01,0x06,0x00,0x00,0x00, + // 0x03,0x0b,0x25,0x00,0x00,0x50,0x56,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + // 0x7f,0xff,0x04,0x00} + // + EFI_DEVICE_PATH_PROTOCOL DevicePath[]; +} REST_EX_SERVICE_DEVICE_PATH_DATA; + +#endif diff --git a/CdeEmuPkg/RedfishPkg/Include/Protocol/EdkIIRedfishConfigHandler.h b/CdeEmuPkg/RedfishPkg/Include/Protocol/EdkIIRedfishConfigHandler.h new file mode 100644 index 00000000000..297bdb85145 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Include/Protocol/EdkIIRedfishConfigHandler.h @@ -0,0 +1,78 @@ +/** @file + This file defines the EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL interface. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EDKII_REDFISH_CONFIG_HANDLER_H_ +#define EDKII_REDFISH_CONFIG_HANDLER_H_ + +typedef struct _EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL; + +#define EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL_GUID \ + { \ + 0xbc0fe6bb, 0x2cc9, 0x463e, { 0x90, 0x82, 0xfa, 0x11, 0x76, 0xfc, 0x67, 0xde } \ + } + +typedef struct { + EFI_HANDLE RedfishServiceRestExHandle; ///< REST EX EFI handle associated with this Redfish service. + UINTN RedfishServiceVersion; ///< Redfish service version. + CHAR16 *RedfishServiceLocation; ///< Redfish service location. + CHAR16 *RedfishServiceUuid; ///< Redfish service UUID. + CHAR16 *RedfishServiceOs; ///< Redfish service OS. + CHAR16 *RedfishServiceOsVersion; ///< Redfish service OS version. + CHAR16 *RedfishServiceProduct; ///< Redfish service product name. + CHAR16 *RedfishServiceProductVer; ///< Redfish service product version. + BOOLEAN RedfishServiceUseHttps; ///< Redfish service uses HTTPS. +} REDFISH_CONFIG_SERVICE_INFORMATION; + +/** + Initialize a configure handler of EDKII Redfish feature driver. + + This function will be called by the EDKII Redfish config handler driver to + initialize the configure handler of each EDKII Redfish feature driver. + + @param[in] This Pointer to EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL instance. + @param[in] RedfishServiceinfo Redfish service information. + + @retval EFI_SUCCESS The handler has been initialized successfully. + @retval EFI_DEVICE_ERROR Failed to create or configure the REST EX protocol instance. + @retval EFI_ALREADY_STARTED This handler has already been initialized. + @retval Other Error happens during the initialization. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL_INIT) ( + IN EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *This, + IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishServiceinfo + ); + +/** + Stop a Redfish configure handler of EDKII Redfish feature driver. + + @param[in] This Pointer to EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL instance. + + @retval EFI_SUCCESS This handler has been stoped successfully. + @retval Others Some error happened. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL_STOP) ( + IN EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *This + ); + +struct _EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL { + EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL_INIT Init; + EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL_STOP Stop; +}; + + +extern EFI_GUID gdkIIRedfishConfigHandlerProtocolGuid; + +#endif diff --git a/CdeEmuPkg/RedfishPkg/Include/Protocol/EdkIIRedfishCredential.h b/CdeEmuPkg/RedfishPkg/Include/Protocol/EdkIIRedfishCredential.h new file mode 100644 index 00000000000..40a4231d5ad --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Include/Protocol/EdkIIRedfishCredential.h @@ -0,0 +1,101 @@ +/** @file + This file defines the EDKII_REDFISH_CREDENTIAL_PROTOCOL interface. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EDKII_REDFISH_CREDENTIAL_H_ +#define EDKII_REDFISH_CREDENTIAL_H_ + +typedef struct _EDKII_REDFISH_CREDENTIAL_PROTOCOL EDKII_REDFISH_CREDENTIAL_PROTOCOL; + +#define EDKII_REDFISH_CREDENTIAL_PROTOCOL_GUID \ + { \ + 0x8804377, 0xaf7a, 0x4496, { 0x8a, 0x7b, 0x17, 0x59, 0x0, 0xe9, 0xab, 0x46 } \ + } + +typedef enum { + AuthMethodNone, ///< No authentication is required. + AuthMethodHttpBasic, ///< Basic authentication is required. + AuthMethodRedfishSession, ///< Session authentication is required. + AuthMethodMax +} EDKII_REDFISH_AUTH_METHOD; + +typedef enum { + ServiceStopTypeNone = 0, ///< Stop Redfsih service without reason. + ServiceStopTypeSecureBootDisabled, ///< Stop Redfsih service becasue EFI + ///< Secure Boot is disabled. + ServiceStopTypeExitBootService, ///< Stop Redfsih service becasue existing + ///< Boot Service. + ServiceStopTypeMax +} EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE; + + +/** + Retrieve platform's Redfish authentication information. + + This functions returns the Redfish authentication method together with the user Id and + password. + - For AuthMethodNone, the UserId and Password could be used for HTTP header authentication + as defined by RFC7235. + - For AuthMethodRedfishSession, the UserId and Password could be used for Redfish + session login as defined by Redfish API specification (DSP0266). + + Callers are responsible for and freeing the returned string storage. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + @param[out] AuthMethod Type of Redfish authentication method. + @param[out] UserId The pointer to store the returned UserId string. + @param[out] Password The pointer to store the returned Password string. + + @retval EFI_SUCCESS Get the authentication information successfully. + @retval EFI_ACCESS_DENIED SecureBoot is disabled after EndOfDxe. + @retval EFI_INVALID_PARAMETER This or AuthMethod or UserId or Password is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough memory resources. + @retval EFI_UNSUPPORTED Unsupported authentication method is found. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_REDFISH_CREDENTIAL_PROTOCOL_GET_AUTH_INFO) ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, + OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod, + OUT CHAR8 **UserId, + OUT CHAR8 **Password + ); + +/** + Notify the Redfish service provide to stop provide configuration service to this platform. + + This function should be called when the platfrom is about to leave the safe environment. + It will notify the Redfish service provider to abort all logined session, and prohibit + further login with original auth info. GetAuthInfo() will return EFI_UNSUPPORTED once this + function is returned. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + @param[in] ServiceStopType Reason of stopping Redfish service. + + @retval EFI_SUCCESS Service has been stoped successfully. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval Others Some error happened. + +**/ +typedef +EFI_STATUS +(EFIAPI *EDKII_REDFISH_CREDENTIAL_PROTOCOL_STOP_SERVICE) ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, + IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType + ); + +struct _EDKII_REDFISH_CREDENTIAL_PROTOCOL { + EDKII_REDFISH_CREDENTIAL_PROTOCOL_GET_AUTH_INFO GetAuthInfo; + EDKII_REDFISH_CREDENTIAL_PROTOCOL_STOP_SERVICE StopService; +}; + +extern EFI_GUID gEdkIIRedfishCredentialProtocolGuid; + +#endif diff --git a/CdeEmuPkg/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c b/CdeEmuPkg/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c new file mode 100644 index 00000000000..33afadb366d --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c @@ -0,0 +1,421 @@ +/** @file + UCS2 to UTF8 manipulation library. + + Copyright (c) 2018 - 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 + +/** + Since each UCS2 character can be represented by 1-3 UTF8 encoded characters, + this function is used to retrieve the UTF8 encoding size for a UCS2 character. + + @param[in] Utf8Buffer The buffer for UTF8 encoded data. + + @retval Return the size of UTF8 encoding string or 0 if it is not for + UCS2 format. + +**/ +UINT8 +GetUTF8SizeForUCS2 ( + IN CHAR8 *Utf8Buffer + ) +{ + CHAR8 TempChar; + UINT8 Utf8Size; + + ASSERT (Utf8Buffer != NULL); + + TempChar = *Utf8Buffer; + if ((TempChar & 0xF0) == 0xF0) { + + // + // This format is not for UCS2. + // + return 0; + } + + Utf8Size = 1; + if ((TempChar & 0x80) == 0x80) { + if ((TempChar & 0xC0) == 0xC0) { + + Utf8Size ++; + if ((TempChar & 0xE0) == 0xE0) { + + Utf8Size ++; + } + } + } + + return Utf8Size; +} + +/** + Since each UCS2 character can be represented by the format: \uXXXX, this function + is used to retrieve the UCS2 character from a Unicode format. + Call MUST make sure there are at least 6 Bytes in the input UTF8 buffer. + + @param[in] Utf8Buffer The buffer for UTF8 encoded data. + @param[out] Ucs2Char The converted UCS2 character. + + @retval EFI_INVALID_PARAMETER Non-Ascii characters found in the hexadecimal + digits string, and can't be converted to a UCS2 + character. + @retval EFI_SUCCESS The UCS2 character has been retrieved. + +**/ +EFI_STATUS +GetUCS2CharByFormat ( + IN CHAR8 *Utf8Buffer, + OUT CHAR16 *Ucs2Char + ) +{ + UINT8 Num1; + UINT8 Num2; + UINT8 Index; + CHAR8 Ucs2CharFormat[UNICODE_FORMAT_CHAR_SIZE]; /// two Hexadecimal digits Ascii string, like "3F" + + for (Index = 0; Index < 4; Index ++) { + if ((*(Utf8Buffer + 2 + Index) & 0x80) != 0x00) { + return EFI_INVALID_PARAMETER; + } + } + + ZeroMem (Ucs2CharFormat, UNICODE_FORMAT_CHAR_SIZE); + + // + // Get the First Number, Offset is 2 + // + CopyMem (Ucs2CharFormat, Utf8Buffer + 2, UNICODE_FORMAT_CHAR_LEN); + Num1 = (UINT8) AsciiStrHexToUintn (Ucs2CharFormat); + + // + // Get the Second Number, Offset is 4 + // + CopyMem (Ucs2CharFormat, Utf8Buffer + 4, UNICODE_FORMAT_CHAR_LEN); + Num2 = (UINT8) AsciiStrHexToUintn (Ucs2CharFormat); + + // + // Ucs2Char is Little-Endian + // + *((CHAR8 *) Ucs2Char) = Num2; + *(((CHAR8 *) Ucs2Char) + 1) = Num1; + + return EFI_SUCCESS; +} + +/** + Convert a UCS2 character to UTF8 encoding string. + + @param[in] Ucs2Char The provided UCS2 character. + @param[out] Utf8Buffer The converted UTF8 encoded data. + + @retval Return the size of UTF8 encoding data for this UCS2 character. + +**/ +UINT8 +UCS2CharToUTF8 ( + IN CHAR16 Ucs2Char, + OUT CHAR8 *Utf8Buffer + ) +{ + UINT16 Ucs2Number; + + ASSERT (Utf8Buffer != NULL); + + Ucs2Number = (UINT16) Ucs2Char; + if (Ucs2Number <= 0x007F) { + + // + // UTF8 format: 0xxxxxxx + // + *Utf8Buffer = Ucs2Char & 0x7F; + return 1; + + } else if (Ucs2Number >= 0x0080 && Ucs2Number <= 0x07FF) { + + // + // UTF8 format: 110xxxxx 10xxxxxx + // + *(Utf8Buffer + 1) = (Ucs2Char & 0x3F) | 0x80; + *Utf8Buffer = ((Ucs2Char >> 6) & 0x1F) | 0xC0; + return 2; + + } else { /// Ucs2Number >= 0x0800 && Ucs2Number <= 0xFFFF + + // + // UTF8 format: 1110xxxx 10xxxxxx 10xxxxxx + // + *(Utf8Buffer + 2) = (Ucs2Char & 0x3F) | 0x80; + *(Utf8Buffer + 1) = ((Ucs2Char >> 6) & 0x3F) | 0x80; + *Utf8Buffer = ((Ucs2Char >> 12) & 0x0F) | 0xE0; + return 3; + } +} + +/** + Convert a UTF8 encoded data to a UCS2 character. + + @param[in] Utf8Buffer The provided UTF8 encoded data. + @param[out] Ucs2Char The converted UCS2 character. + + @retval EFI_INVALID_PARAMETER The UTF8 encoded string is not valid or + not for UCS2 character. + @retval EFI_SUCCESS The converted UCS2 character. + +**/ +EFI_STATUS +UTF8ToUCS2Char ( + IN CHAR8 *Utf8Buffer, + OUT CHAR16 *Ucs2Char + ) +{ + UINT8 Utf8Size; + CHAR8 *Ucs2Buffer; + CHAR8 TempChar1; + CHAR8 TempChar2; + CHAR8 TempChar3; + + ASSERT (Utf8Buffer != NULL && Ucs2Char != NULL); + ZeroMem (Ucs2Char, sizeof (CHAR16)); + Ucs2Buffer = (CHAR8 *) Ucs2Char; + + Utf8Size = GetUTF8SizeForUCS2 (Utf8Buffer); + switch (Utf8Size) { + + case 1: + + // + // UTF8 format: 0xxxxxxx + // + TempChar1 = *Utf8Buffer; + if ((TempChar1 & 0x80) != 0x00) { + return EFI_INVALID_PARAMETER; + } + + *Ucs2Buffer = TempChar1; + *(Ucs2Buffer + 1) = 0; + break; + + case 2: + + // + // UTF8 format: 110xxxxx 10xxxxxx + // + TempChar1 = *Utf8Buffer; + if ((TempChar1 & 0xE0) != 0xC0) { + return EFI_INVALID_PARAMETER; + } + + TempChar2 = *(Utf8Buffer + 1); + if ((TempChar2 & 0xC0) != 0x80) { + return EFI_INVALID_PARAMETER; + } + + *Ucs2Buffer = (TempChar1 << 6) + (TempChar2 & 0x3F); + *(Ucs2Buffer + 1) = (TempChar1 >> 2) & 0x07; + break; + + case 3: + + // + // UTF8 format: 1110xxxx 10xxxxxx 10xxxxxx + // + TempChar1 = *Utf8Buffer; + if ((TempChar1 & 0xF0) != 0xE0) { + return EFI_INVALID_PARAMETER; + } + + TempChar2 = *(Utf8Buffer + 1); + if ((TempChar2 & 0xC0) != 0x80) { + return EFI_INVALID_PARAMETER; + } + + TempChar3 = *(Utf8Buffer + 2); + if ((TempChar3 & 0xC0) != 0x80) { + return EFI_INVALID_PARAMETER; + } + + *Ucs2Buffer = (TempChar2 << 6) + (TempChar3 & 0x3F); + *(Ucs2Buffer + 1) = (TempChar1 << 4) + ((TempChar2 >> 2) & 0x0F); + + break; + + default: + + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +/** + Convert a UCS2 string to a UTF8 encoded string. + + @param[in] Ucs2Str The provided UCS2 string. + @param[out] Utf8StrAddr The converted UTF8 string address. Caller + is responsible for Free this string. + + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES System runs out of resources. + @retval EFI_SUCCESS The UTF8 encoded string has been converted. + +**/ +EFI_STATUS +UCS2StrToUTF8 ( + IN CHAR16 *Ucs2Str, + OUT CHAR8 **Utf8StrAddr + ) +{ + UINTN Ucs2StrIndex; + UINTN Ucs2StrLength; + CHAR8 *Utf8Str; + UINTN Utf8StrLength; + UINTN Utf8StrIndex; + CHAR8 Utf8Buffer[UTF8_BUFFER_FOR_UCS2_MAX_SIZE]; + UINT8 Utf8BufferSize; + + if (Ucs2Str == NULL || Utf8StrAddr == NULL) { + return EFI_INVALID_PARAMETER; + } + + Ucs2StrLength = StrLen (Ucs2Str); + Utf8StrLength = 0; + + for (Ucs2StrIndex = 0; Ucs2StrIndex < Ucs2StrLength; Ucs2StrIndex ++) { + + ZeroMem (Utf8Buffer, sizeof (Utf8Buffer)); + Utf8BufferSize = UCS2CharToUTF8 (Ucs2Str[Ucs2StrIndex], Utf8Buffer); + Utf8StrLength += Utf8BufferSize; + } + + Utf8Str = AllocateZeroPool (Utf8StrLength + 1); + if (Utf8Str == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Utf8StrIndex = 0; + for (Ucs2StrIndex = 0; Ucs2StrIndex < Ucs2StrLength; Ucs2StrIndex ++) { + + ZeroMem (Utf8Buffer, sizeof (Utf8Buffer)); + Utf8BufferSize = UCS2CharToUTF8 (Ucs2Str[Ucs2StrIndex], Utf8Buffer); + + CopyMem (Utf8Str + Utf8StrIndex, Utf8Buffer, Utf8BufferSize); + Utf8StrIndex += Utf8BufferSize; + } + + Utf8Str[Utf8StrIndex] = '\0'; + *Utf8StrAddr = Utf8Str; + + return EFI_SUCCESS; +} + +/** + Convert a UTF8 encoded string to a UCS2 string. + + @param[in] Utf8Str The provided UTF8 encoded string. + @param[out] Ucs2StrAddr The converted UCS2 string address. Caller + is responsible for Free this string. + + @retval EFI_INVALID_PARAMETER The UTF8 encoded string is not valid to + convert to UCS2 string. + One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES System runs out of resources. + @retval EFI_SUCCESS The UCS2 string has been converted. + +**/ +EFI_STATUS +UTF8StrToUCS2 ( + IN CHAR8 *Utf8Str, + OUT CHAR16 **Ucs2StrAddr + ) +{ + EFI_STATUS Status; + UINTN Utf8StrIndex; + UINTN Utf8StrLength; + UINTN Ucs2StrIndex; + UINT8 Utf8BufferSize; + CHAR16 *Ucs2StrTemp; + + if (Utf8Str == NULL || Ucs2StrAddr == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // It is not an Ascii string, calculate string length. + // + Utf8StrLength = 0; + while (*(Utf8Str + Utf8StrLength) != '\0') { + Utf8StrLength ++; + } + + // + // UCS2 string shall not be longer than the UTF8 string. + // + Ucs2StrTemp = AllocateZeroPool ((Utf8StrLength + 1) * sizeof (CHAR16)); + if (Ucs2StrTemp == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Utf8StrIndex = 0; + Ucs2StrIndex = 0; + while (Utf8Str[Utf8StrIndex] != '\0') { + + if (CompareMem (Utf8Str + Utf8StrIndex, "\\u", 2) == 0 && + Utf8StrLength - Utf8StrIndex >= UNICODE_FORMAT_LEN) { + + Status = GetUCS2CharByFormat (Utf8Str + Utf8StrIndex, Ucs2StrTemp + Ucs2StrIndex); + if (!EFI_ERROR (Status)) { + + Utf8StrIndex += UNICODE_FORMAT_LEN; + Ucs2StrIndex ++; + } else { + + StrCpyS (Ucs2StrTemp + Ucs2StrIndex, 3, L"\\u"); + + Ucs2StrIndex += 2; + Utf8StrIndex += 2; + } + } else { + + Utf8BufferSize = GetUTF8SizeForUCS2 (Utf8Str + Utf8StrIndex); + if (Utf8BufferSize == 0 || Utf8StrLength - Utf8StrIndex < Utf8BufferSize) { + + FreePool (Ucs2StrTemp); + return EFI_INVALID_PARAMETER; + } + + Status = UTF8ToUCS2Char (Utf8Str + Utf8StrIndex, Ucs2StrTemp + Ucs2StrIndex); + if (EFI_ERROR (Status)) { + + FreePool (Ucs2StrTemp); + return EFI_INVALID_PARAMETER; + } + + Ucs2StrIndex ++; + Utf8StrIndex += Utf8BufferSize; + } + } + + *Ucs2StrAddr = AllocateZeroPool ((Ucs2StrIndex + 1) * sizeof (CHAR16)); + if (*Ucs2StrAddr == NULL) { + + FreePool (Ucs2StrTemp); + return EFI_OUT_OF_RESOURCES; + } + + StrCpyS (*Ucs2StrAddr, Ucs2StrIndex + 1, Ucs2StrTemp); + *(*Ucs2StrAddr + Ucs2StrIndex) = L'\0'; + FreePool (Ucs2StrTemp); + + return EFI_SUCCESS; +} + diff --git a/CdeEmuPkg/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf b/CdeEmuPkg/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf new file mode 100644 index 00000000000..6b1c315100c --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf @@ -0,0 +1,31 @@ +## @file +# UCS2 to UTF8 manipulation library. +# +# 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 = 0x0001001b + BASE_NAME = BaseUcs2Utf8Lib + FILE_GUID = 536646C3-46D0-4B12-ABC4-CDE1A33B5256 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = Ucs2Utf8Lib + +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64 +# + +[Sources] + BaseUcs2Utf8Lib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + + diff --git a/CdeEmuPkg/RedfishPkg/Library/DxeRestExLib/DxeRestExLib.c b/CdeEmuPkg/RedfishPkg/Library/DxeRestExLib/DxeRestExLib.c new file mode 100644 index 00000000000..4c76166d12f --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/DxeRestExLib/DxeRestExLib.c @@ -0,0 +1,166 @@ +/** @file + This library provides help functions for REST EX Protocol. + + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +#define REST_EX_CONFIG_DATA_LEN_UNKNOWN 0xff + +/** + This function allows the caller to create child handle for specific + REST server. + + @param[in] Image The image handle used to open service. + @param[in] AccessMode Access mode of REST server. + @param[in] ConfigType Underlying configuration to communicate with REST server. + @param[in] ServiceType REST service type. + @param[out] ChildInstanceHandle The handle to receive the create child. + + @retval EFI_SUCCESS Can't create the corresponding REST EX child instance. + @retval EFI_INVALID_PARAMETERS Any of input parameters is improper. + +**/ +EFI_STATUS +RestExLibCreateChild ( + IN EFI_HANDLE Image, + IN EFI_REST_EX_SERVICE_ACCESS_MODE AccessMode, + IN EFI_REST_EX_CONFIG_TYPE ConfigType, + IN EFI_REST_EX_SERVICE_TYPE ServiceType, + OUT EFI_HANDLE *ChildInstanceHandle +) +{ + EFI_STATUS Status; + UINTN NoBuffer; + EFI_HANDLE *Handle; + EFI_HANDLE ChildHandle; + EFI_REST_EX_PROTOCOL *RestEx; + EFI_REST_EX_SERVICE_INFO *RestExServiceInfo; + UINT8 LenOfConfig; + + if (Image == NULL || + AccessMode >= EfiRestExServiceModeMax || + ConfigType >= EfiRestExConfigTypeMax || + ServiceType >= EfiRestExServiceTypeMax || + ChildInstanceHandle == NULL + ) { + return EFI_INVALID_PARAMETER; + } + + *ChildInstanceHandle = NULL; + // + // Locate all REST EX binding service. + // + Handle = NULL; + NoBuffer = 0; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiRestExServiceBindingProtocolGuid, + NULL, + &NoBuffer, + &Handle + ); + if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { + return Status; + } + Handle = (EFI_HANDLE *)AllocateZeroPool (sizeof(EFI_HANDLE) * NoBuffer); + if (Handle == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiRestExServiceBindingProtocolGuid, + NULL, + &NoBuffer, + &Handle + ); + if (EFI_ERROR (Status)) { + FreePool (Handle); + return Status; + } + + // + // Search for the proper REST EX instance. + // + while (NoBuffer != 0) { + ChildHandle = NULL; + Status = NetLibCreateServiceChild ( + *(Handle + (NoBuffer - 1)), + Image, + &gEfiRestExServiceBindingProtocolGuid, + &ChildHandle + ); + if (!EFI_ERROR (Status)) { + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiRestExProtocolGuid, + (VOID **)&RestEx, + Image, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + // + // Get the information of REST service provided by this EFI REST EX driver + // + Status = RestEx->GetService ( + RestEx, + &RestExServiceInfo + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + // + // Check REST EX property. + // + switch (ConfigType) { + case EfiRestExConfigHttp: + LenOfConfig = sizeof (EFI_REST_EX_HTTP_CONFIG_DATA); + break; + + case EfiRestExConfigUnspecific: + LenOfConfig = REST_EX_CONFIG_DATA_LEN_UNKNOWN; + break; + + default: + goto ON_ERROR; + } + if (RestExServiceInfo->EfiRestExServiceInfoV10.RestServiceAccessMode != AccessMode || + RestExServiceInfo->EfiRestExServiceInfoV10.RestServiceType != ServiceType || + RestExServiceInfo->EfiRestExServiceInfoV10.RestExConfigType != ConfigType || + ((LenOfConfig != REST_EX_CONFIG_DATA_LEN_UNKNOWN) && (RestExServiceInfo->EfiRestExServiceInfoV10.RestExConfigDataLength != LenOfConfig))) { + goto ON_ERROR; + } + } + // + // This is proper REST EX instance. + // + *ChildInstanceHandle = ChildHandle; + FreePool (Handle); + return EFI_SUCCESS; + +ON_ERROR:; + NetLibDestroyServiceChild ( + *(Handle + (NoBuffer - 1)), + Image, + &gEfiRestExServiceBindingProtocolGuid, + ChildHandle + ); + NoBuffer --; + }; + FreePool (Handle); + return EFI_NOT_FOUND; +} diff --git a/CdeEmuPkg/RedfishPkg/Library/DxeRestExLib/DxeRestExLib.inf b/CdeEmuPkg/RedfishPkg/Library/DxeRestExLib/DxeRestExLib.inf new file mode 100644 index 00000000000..416dc630510 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/DxeRestExLib/DxeRestExLib.inf @@ -0,0 +1,44 @@ +## @file +# Library for REST EX Protocol +# +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001b + BASE_NAME = DxeRestExLib + FILE_GUID = E9CBF727-8AF3-4602-9DBD-A3942869B5AE + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = RestExLib | DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER + +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC RISCV64 +# + +[Sources.common] + DxeRestExLib.c + +[Packages] + NetworkPkg/NetworkPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DevicePathLib + MemoryAllocationLib + NetLib + PrintLib + UefiLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + +[Protocols] + gEfiRestExServiceBindingProtocolGuid ## PROTOCOL ALWAYS_CONSUMED + gEfiRestExProtocolGuid ## PROTOCOL ALWAYS_CONSUMED + diff --git a/CdeEmuPkg/RedfishPkg/Library/JsonLib/JsonLib.c b/CdeEmuPkg/RedfishPkg/Library/JsonLib/JsonLib.c new file mode 100644 index 00000000000..f30e9c4b2bc --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/JsonLib/JsonLib.c @@ -0,0 +1,1111 @@ +/** @file + APIs for JSON operations. The fuctions provided by this library are the + wrapper to native open source jansson library. See below document for + the API reference. + https://jansson.readthedocs.io/en/2.13/apiref.html + + Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include +#include + +#include "jansson.h" + +/** + The function is used to initialize a JSON value which contains a new JSON array, + or NULL on error. Initially, the array is empty. + + The reference count of this value will be set to 1, and caller needs to cleanup the + value by calling JsonValueFree(). + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @retval The created JSON value which contains a JSON array or NULL if intial a JSON array + is failed. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitArray ( + VOID + ) +{ + return (EDKII_JSON_VALUE)json_array(); +} + +/** + The function is used to initialize a JSON value which contains a new JSON object, + or NULL on error. Initially, the object is empty. + + The reference count of this value will be set to 1, and caller needs to cleanup the + value by calling JsonValueFree(). + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @retval The created JSON value which contains a JSON object or NULL if intial a JSON object + is failed. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitObject ( + VOID + ) +{ + return (EDKII_JSON_VALUE)json_object(); +} + +/** + The function is used to initialize a JSON value which contains a new JSON string, + or NULL on error. + + The input string must be NULL terminated Ascii format, non-Ascii characters will + be processed as an error. Unicode characters can also be represented by Ascii string + as the format: \u + 4 hexadecimal digits, like \u3E5A, or \u003F. + + The reference count of this value will be set to 1, and caller needs to cleanup the + value by calling JsonValueFree(). + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @param[in] String The Ascii string to initialize to JSON value + + @retval The created JSON value which contains a JSON string or NULL. Select a + Getter API for a specific encoding format. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitAsciiString ( + IN CONST CHAR8 *String + ) +{ + UINTN Index; + + if (String == NULL) { + return NULL; + } + + Index = 0; + while (*(String + Index) != '\0') { + if (((*(String + Index)) & 0x80) != 0x00) { + return NULL; + } + + Index++; + } + + return (EDKII_JSON_VALUE)json_string (String); +} + +/** + The function is used to initialize a JSON value which contains a new JSON string, + or NULL on error. + + The input must be a NULL terminated UCS2 format Unicode string. + + The reference count of this value will be set to 1, and caller needs to cleanup the + value by calling JsonValueFree(). + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @param[in] String The Unicode string to initialize to JSON value + + @retval The created JSON value which contains a JSON string or NULL. Select a + Getter API for a specific encoding format. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitUnicodeString ( + IN CHAR16 *String + ) +{ + EFI_STATUS Status; + CHAR8 *Utf8Str; + + if (String == NULL) { + return NULL; + } + + Utf8Str = NULL; + Status = UCS2StrToUTF8 (String, &Utf8Str); + if (EFI_ERROR (Status)) { + return NULL; + } + + return (EDKII_JSON_VALUE)json_string (Utf8Str); +} + +/** + The function is used to initialize a JSON value which contains a new JSON integer, + or NULL on error. + + The reference count of this value will be set to 1, and caller needs to cleanup the + value by calling JsonValueFree(). + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @param[in] Value The integer to initialize to JSON value + + @retval The created JSON value which contains a JSON integer or NULL. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitInteger ( + IN INT64 Value + ) +{ + return (EDKII_JSON_VALUE)json_integer (Value); +} + +/** + The function is used to initialize a JSON value which contains a new JSON boolean, + or NULL on error. + + Boolean JSON value is kept as static value, and no need to do any cleanup work. + + @param[in] Value The boolean value to initialize. + + @retval The created JSON value which contains a JSON boolean or NULL. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitBoolean ( + IN BOOLEAN Value + ) +{ + return (EDKII_JSON_VALUE)json_boolean (Value); +} + +/** + The function is used to initialize a JSON value which contains a TRUE JSON value, + or NULL on error. + + NULL JSON value is kept as static value, and no need to do any cleanup work. + + @retval The created JSON TRUE value. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitTrue ( + VOID + ) +{ + return (EDKII_JSON_VALUE)json_true(); +} + +/** + The function is used to initialize a JSON value which contains a FALSE JSON value, + or NULL on error. + + NULL JSON value is kept as static value, and no need to do any cleanup work. + + @retval The created JSON FALSE value. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitFalse ( + VOID + ) +{ + return (EDKII_JSON_VALUE)json_false(); +} + +/** + The function is used to initialize a JSON value which contains a new JSON NULL, + or NULL on error. + + NULL JSON value is kept as static value, and no need to do any cleanup work. + + @retval The created NULL JSON value. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueInitNull ( + VOID + ) +{ + return (EDKII_JSON_VALUE)json_null(); +} + +/** + The function is used to decrease the reference count of a JSON value by one, and once + this reference count drops to zero, the value is destroyed and it can no longer be used. + If this destroyed value is object type or array type, reference counts for all containing + JSON values will be decreased by 1. Boolean JSON value and NULL JSON value won't be destroyed + since they are static values kept in memory. + + Reference Count Strategy: BaseJsonLib uses this strategy to track whether a value is still + in use or not. When a value is created, it's reference count is set to 1. If a reference to a + value is kept for use, its reference count is incremented, and when the value is no longer + needed, the reference count is decremented. When the reference count drops to zero, there are + no references left, and the value can be destroyed. + + The given JSON value maybe NULL and not causing any problem. Just output the debug message + to inform caller the NULL value is passed in. + + @param[in] Json The JSON value to be freed. json_decref may return without any + changes if Json is NULL. + +**/ +VOID +EFIAPI +JsonValueFree ( + IN EDKII_JSON_VALUE Json + ) +{ + json_decref((json_t *)Json); +} + +/** + The function is used to create a fresh copy of a JSON value, and all child values are deep + copied in a recursive fashion. It should be called when this JSON value might be modified + in later use, but the original still wants to be used in somewhere else. + + Reference counts of the returned root JSON value and all child values will be set to 1, and + caller needs to cleanup the root value by calling JsonValueFree(). + + * Note: Since this function performs a copy from bottom to up, too many calls may cause some + performance issues, user should avoid unnecessary calls to this function unless it is really + needed. + + @param[in] Json The JSON value to be cloned. + + @retval Return the cloned JSON value, or NULL on error. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonValueClone ( + IN EDKII_JSON_VALUE Json + ) +{ + return (EDKII_JSON_VALUE)json_deep_copy ((json_t *) Json); +} + +/** + The function is used to return if the provided JSON value contains a JSON array. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a JSON array. + @retval FALSE The JSON value doesn't contain a JSON array. + +**/ +BOOLEAN +EFIAPI +JsonValueIsArray ( + IN EDKII_JSON_VALUE Json + ) +{ + return json_is_array ((json_t *) Json); +} + +/** + The function is used to return if the provided JSON value contains a JSON object. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a JSON object. + @retval FALSE The JSON value doesn't contain a JSON object. + +**/ +BOOLEAN +EFIAPI +JsonValueIsObject ( + IN EDKII_JSON_VALUE Json + ) +{ + return json_is_object ((json_t *) Json); +} + +/** + The function is used to return if the provided JSON Value contains a string, Ascii or + Unicode format is not differentiated. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a JSON string. + @retval FALSE The JSON value doesn't contain a JSON string. + +**/ +BOOLEAN +EFIAPI +JsonValueIsString ( + IN EDKII_JSON_VALUE Json + ) +{ + return json_is_string ((json_t *) Json); +} + +/** + The function is used to return if the provided JSON value contains a JSON integer. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value is contains JSON integer. + @retval FALSE The JSON value doesn't contain a JSON integer. + +**/ +BOOLEAN +EFIAPI +JsonValueIsInteger ( + IN EDKII_JSON_VALUE Json + ) +{ + return json_is_integer ((json_t *) Json); +} + +/** + The function is used to return if the provided JSON value contains a JSON number. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value is contains JSON number. + @retval FALSE The JSON value doesn't contain a JSON number. + +**/ +BOOLEAN +EFIAPI +JsonValueIsNumber ( + IN EDKII_JSON_VALUE Json + ) +{ + return json_is_number ((json_t *) Json); +} + +/** + The function is used to return if the provided JSON value contains a JSON boolean. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a JSON boolean. + @retval FALSE The JSON value doesn't contain a JSON boolean. + +**/ +BOOLEAN +EFIAPI +JsonValueIsBoolean ( + IN EDKII_JSON_VALUE Json + ) +{ + return json_is_boolean ((json_t *) Json); +} + +/** + The function is used to return if the provided JSON value contains a TRUE value. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a TRUE value. + @retval FALSE The JSON value doesn't contain a TRUE value. + +**/ +BOOLEAN +EFIAPI +JsonValueIsTrue ( + IN EDKII_JSON_VALUE Json + ) +{ + if (json_is_true ((json_t *)Json)) { + return TRUE; + } + return FALSE; +} + +/** + The function is used to return if the provided JSON value contains a FALSE value. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a FALSE value. + @retval FALSE The JSON value doesn't contain a FALSE value. + +**/ +BOOLEAN +EFIAPI +JsonValueIsFalse ( + IN EDKII_JSON_VALUE Json + ) +{ + if (json_is_false ((json_t *)Json)) { + return TRUE; + } + return FALSE; +} +/** + The function is used to return if the provided JSON value contains a JSON NULL. + + @param[in] Json The provided JSON value. + + @retval TRUE The JSON value contains a JSON NULL. + @retval FALSE The JSON value doesn't contain a JSON NULL. + +**/ +BOOLEAN +EFIAPI +JsonValueIsNull ( + IN EDKII_JSON_VALUE Json + ) +{ + return json_is_null ((json_t *) Json); +} + +/** + The function is used to retrieve the associated array in an array type JSON value. + + Any changes to the returned array will impact the original JSON value. + + @param[in] Json The provided JSON value. + + @retval Return the associated array in JSON value or NULL. + +**/ +EDKII_JSON_ARRAY +EFIAPI +JsonValueGetArray ( + IN EDKII_JSON_VALUE Json + ) +{ + if (Json == NULL || !JsonValueIsArray (Json)) { + return NULL; + } + + return (EDKII_JSON_ARRAY)Json; +} + +/** + The function is used to retrieve the associated object in an object type JSON value. + + Any changes to the returned object will impact the original JSON value. + + @param[in] Json The provided JSON value. + + @retval Return the associated object in JSON value or NULL. + +**/ +EDKII_JSON_OBJECT +EFIAPI +JsonValueGetObject ( + IN EDKII_JSON_VALUE Json + ) +{ + if (Json == NULL || !JsonValueIsObject (Json)) { + return NULL; + } + + return (EDKII_JSON_OBJECT)Json; +} + +/** + The function is used to retrieve the associated Ascii string in a string type JSON value. + + Any changes to the returned string will impact the original JSON value. + + @param[in] Json The provided JSON value. + + @retval Return the associated Ascii string in JSON value or NULL. + +**/ +CONST CHAR8 * +EFIAPI +JsonValueGetAsciiString ( + IN EDKII_JSON_VALUE Json + ) +{ + CONST CHAR8 *AsciiStr; + UINTN Index; + + AsciiStr = json_string_value ((json_t *) Json); + if (AsciiStr == NULL) { + return NULL; + } + + Index = 0; + while (*(AsciiStr + Index) != '\0') { + if (((*(AsciiStr + Index)) & 0x80) != 0x00) { + return NULL; + } + + Index++; + } + + return AsciiStr; +} + +/** + The function is used to retrieve the associated Unicode string in a string type JSON value. + + Caller can do any changes to the returned string without any impact to the original JSON + value, and caller needs to free the returned string using FreePool(). + + @param[in] Json The provided JSON value. + + @retval Return the associated Unicode string in JSON value or NULL. + +**/ +CHAR16* +EFIAPI +JsonValueGetUnicodeString ( + IN EDKII_JSON_VALUE Json + ) +{ + EFI_STATUS Status; + CONST CHAR8 *Utf8Str; + CHAR16 *Ucs2Str; + + Utf8Str = json_string_value ((json_t *) Json); + if (Utf8Str == NULL) { + return NULL; + } + + Status = UTF8StrToUCS2 ((CHAR8*)Utf8Str, &Ucs2Str); + if (EFI_ERROR (Status)) { + return NULL; + } + + return Ucs2Str; +} + +/** + The function is used to retrieve the associated integer in a integer type JSON value. + + The input JSON value should not be NULL or contain no JSON integer, otherwise it will + ASSERT() and return 0. + + @param[in] Json The provided JSON value. + + @retval Return the associated integer in JSON value. + +**/ +INT64 +EFIAPI +JsonValueGetInteger ( + IN EDKII_JSON_VALUE Json + ) +{ + ASSERT (Json != NULL && JsonValueIsInteger (Json)); + if (Json == NULL || !JsonValueIsInteger (Json)) { + return 0; + } + + return json_integer_value ((json_t *) Json); +} + +/** + The function is used to retrieve the associated boolean in a boolean type JSON value. + + The input JSON value should not be NULL or contain no JSON boolean, otherwise it will + ASSERT() and return FALSE. + + @param[in] Json The provided JSON value. + + @retval Return the associated value of JSON boolean. + +**/ +BOOLEAN +EFIAPI +JsonValueGetBoolean ( + IN EDKII_JSON_VALUE Json + ) +{ + ASSERT (Json != NULL && JsonValueIsBoolean (Json)); + if (Json == NULL || !JsonValueIsBoolean (Json)) { + return FALSE; + } + + return json_is_true ((json_t *) Json); +} + +/** + The function is used to retrieve the associated string in a string type JSON value. + + Any changes to the returned string will impact the original JSON value. + + @param[in] Json The provided JSON value. + + @retval Return the associated Ascii string in JSON value or NULL on errors. + +**/ +CONST CHAR8* +EFIAPI +JsonValueGetString ( + IN EDKII_JSON_VALUE Json + ) +{ + return json_string_value ((const json_t *)Json); +} + +/** + The function is used to get the number of elements in a JSON object, or 0 if it is NULL or + not a JSON object. + + @param[in] JsonObject The provided JSON object. + + @retval Return the number of elements in this JSON object or 0. + +**/ +UINTN +EFIAPI +JsonObjectSize ( + IN EDKII_JSON_OBJECT JsonObject + ) +{ + return json_object_size ((json_t *) JsonObject); +} + +/** + The function is used to enumerate all keys in a JSON object. + + Caller should be responsible to free the returned key array reference using + FreePool(). But contained keys are read only and must not be modified or freed. + + @param[in] JsonObj The provided JSON object for enumeration. + @param[out] KeyCount The count of keys in this JSON object. + + @retval Return an array of the enumerated keys in this JSON object or NULL if + JsonObj is not an JSON object, key count is zero or on other errors. + +**/ +CHAR8** +JsonObjectGetKeys ( + IN EDKII_JSON_OBJECT JsonObj, + OUT UINTN *KeyCount + ) +{ + + UINTN Index; + CONST CHAR8 **KeyArray; + CONST CHAR8 *Key; + EDKII_JSON_VALUE Value; + + if (JsonObj == NULL || KeyCount == NULL) { + return NULL; + } + + Index = 0; + json_object_foreach(JsonObj, Key, Value) { + Index++; + } + if (Index == 0) { + *KeyCount = 0; + return NULL; + } + + *KeyCount = Index; + KeyArray = (CONST CHAR8 **) AllocateZeroPool (*KeyCount * sizeof (CHAR8 *)); + if (KeyArray == NULL) { + return NULL; + } + + Key = NULL; + Value = NULL; + Index = 0; + json_object_foreach((json_t *) JsonObj, Key, Value) { + KeyArray[Index] = Key; + Index++; + } + + return (CHAR8 **)KeyArray; +} + +/** + The function is used to get a JSON value corresponding to the input key from a JSON object. + + It only returns a reference to this value and any changes on this value will impact the + original JSON object. If that is not expected, please call JsonValueClone() to clone it to + use. + + Input key must be a valid NULL terminated UTF8 encoded string. NULL will be returned when + Key-Value is not found in this JSON object. + + @param[in] JsonObj The provided JSON object. + @param[in] Key The key of the JSON value to be retrieved. + + @retval Return the corresponding JSON value to key, or NULL on error. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonObjectGetValue ( + IN CONST EDKII_JSON_OBJECT JsonObj, + IN CONST CHAR8 *Key + ) +{ + return (EDKII_JSON_VALUE)json_object_get ((const json_t *)JsonObj, (const char *)Key); +} + +/** + The function is used to set a JSON value corresponding to the input key from a JSON object, + and the reference count of this value will be increased by 1. + + Input key must be a valid NULL terminated UTF8 encoded string. If there already is a value for + this key, this key will be assigned to the new JSON value. The old JSON value will be removed + from this object and thus its' reference count will be decreased by 1. + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @param[in] JsonObj The provided JSON object. + @param[in] Key The key of the JSON value to be set. + @param[in] Json The JSON value to set to this JSON object mapped by key. + + @retval EFI_ABORTED Some error occur and operation aborted. + @retval EFI_SUCCESS The JSON value has been set to this JSON object. + +**/ +EFI_STATUS +EFIAPI +JsonObjectSetValue ( + IN EDKII_JSON_OBJECT JsonObj, + IN CONST CHAR8 *Key, + IN EDKII_JSON_VALUE Json + ) +{ + if (json_object_set ((json_t *) JsonObj, Key, (json_t *) Json) != 0) { + return EFI_ABORTED; + } else { + return EFI_SUCCESS; + } +} + +/** + The function is used to get the number of elements in a JSON array. Returns or 0 if JsonArray + is NULL or not a JSON array. + + @param[in] JsonArray The provided JSON array. + + @retval Return the number of elements in this JSON array or 0. + +**/ +UINTN +EFIAPI +JsonArrayCount ( + IN EDKII_JSON_ARRAY JsonArray + ) +{ + return json_array_size ((json_t *) JsonArray); +} + +/** + The function is used to return the JSON value in the array at position index. The valid range + for this index is from 0 to the return value of JsonArrayCount() minus 1. + + It only returns a reference to this value and any changes on this value will impact the + original JSON object. If that is not expected, please call JsonValueClone() to clone it to + use. + + If this array is NULL or not a JSON array, or if index is out of range, NULL will be returned. + + @param[in] JsonArray The provided JSON Array. + + @retval Return the JSON value located in the Index position or + NULL if JsonArray is not an array or no items in the array. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonArrayGetValue ( + IN EDKII_JSON_ARRAY JsonArray, + IN UINTN Index + ) +{ + return (EDKII_JSON_VALUE)json_array_get ((json_t *) JsonArray, Index); +} + +/** + The function is used to append a JSON value to the end of the JSON array, and grow the size of + array by 1. The reference count of this value will be increased by 1. + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @param[in] JsonArray The provided JSON object. + @param[in] Json The JSON value to append. + + @retval EFI_ABORTED Some error occur and operation aborted. + @retval EFI_SUCCESS JSON value has been appended to the end of the JSON array. + +**/ +EFI_STATUS +EFIAPI +JsonArrayAppendValue ( + IN EDKII_JSON_ARRAY JsonArray, + IN EDKII_JSON_VALUE Json + ) +{ + if (json_array_append ((json_t *) JsonArray, (json_t *) Json) != 0) { + return EFI_ABORTED; + } else { + return EFI_SUCCESS; + } +} + +/** + The function is used to remove a JSON value at position index, shifting the elements after index + one position towards the start of the array. The reference count of this value will be decreased + by 1. + + More details for reference count strategy can refer to the API description for JsonValueFree(). + + @param[in] JsonArray The provided JSON array. + @param[in] Index The Index position before removement. + + @retval EFI_ABORTED Some error occur and operation aborted. + @retval EFI_SUCCESS The JSON array has been removed at position index. + +**/ +EFI_STATUS +EFIAPI +JsonArrayRemoveValue ( + IN EDKII_JSON_ARRAY JsonArray, + IN UINTN Index + ) +{ + if (json_array_remove ((json_t *) JsonArray, Index) != 0) { + return EFI_ABORTED; + } else { + return EFI_SUCCESS; + } +} + +/** + Dump JSON to a buffer. + + @param[in] JsonValue The provided JSON value. + @param[in] Flags The Index position before removement. The value + could be the combination of below flags. + - EDKII_JSON_INDENT(n) + - EDKII_JSON_COMPACT + - EDKII_JSON_ENSURE_ASCII + - EDKII_JSON_SORT_KEYS + - EDKII_JSON_PRESERVE_ORDER + - EDKII_JSON_ENCODE_ANY + - EDKII_JSON_ESCAPE_SLASH + - EDKII_JSON_REAL_PRECISION(n) + - EDKII_JSON_EMBED + See below URI for the JSON encoding flags reference. + https://jansson.readthedocs.io/en/2.13/apiref.html#encoding + + @retval CHAR8 * Dump fail if NULL returned, otherwise the buffer + contain JSON paylaod in ASCII string. The return + value must be freed by the caller using FreePool(). +**/ +CHAR8 * +EFIAPI +JsonDumpString ( + IN EDKII_JSON_VALUE JsonValue, + IN UINTN Flags + ) +{ + if (JsonValue == NULL) { + return NULL; + } + return json_dumps((json_t *)JsonValue, Flags); +} + +/** + Convert a string to JSON object. + The function is used to convert a NULL terminated CHAR8 string to a JSON + value. Only object and array represented strings can be converted successfully, + since they are the only valid root values of a JSON text for UEFI usage. + + Real number and number with exponent part are not supportted by UEFI. + + Caller needs to cleanup the root value by calling JsonValueFree(). + + @param[in] String The NULL terminated CHAR8 string to convert. + @param[in] Flags Flags for loading JSON string. + @param[in] Error Returned error status. + + @retval Array JSON value or object JSON value, or NULL when any error occurs. + +**/ +EDKII_JSON_VALUE +EFIAPI +JsonLoadString ( + IN CONST CHAR8* String, + IN UINT64 Flags, + IN EDKII_JSON_ERROR *Error + ) +{ + return (EDKII_JSON_VALUE) json_loads ((const char *)String, Flags, (json_error_t *)Error); +} + +/** + Load JSON from a buffer. + + @param[in] Buffer Bufffer to the JSON payload + @param[in] BufferLen Length of the buffer + @param[in] Flags Flag of loading JSON buffer, the value + could be the combination of below flags. + - EDKII_JSON_REJECT_DUPLICATES + - EDKII_JSON_DISABLE_EOF_CHECK + - EDKII_JSON_DECODE_ANY + - EDKII_JSON_DECODE_INT_AS_REAL + - EDKII_JSON_ALLOW_NUL + See below URI for the JSON encoding flags reference. + https://jansson.readthedocs.io/en/2.13/apiref.html?highlight=json_loadb#decoding + + @param[in,out] Error Pointer EDKII_JSON_ERROR structure + + @retval EDKII_JSON_VALUE NULL means fail to load JSON payload. +**/ +EDKII_JSON_VALUE +EFIAPI +JsonLoadBuffer ( + IN CONST CHAR8 *Buffer, + IN UINTN BufferLen, + IN UINTN Flags, + IN OUT EDKII_JSON_ERROR *Error + ) +{ + return json_loadb(Buffer, BufferLen, Flags, (json_error_t *)Error); +} + +/** + The reference count is used to track whether a value is still in use or not. + When a value is created, it's reference count is set to 1. + when the value is no longer needed, the reference count is decremented. + When the reference count drops to zero, there are no references left and the + value can be destroyed. + + This funciton decrement the reference count of EDKII_JSON_VALUE. As soon as + a call to json_decref() drops the reference count to zero, the value is + destroyed and it can no longer be used. + + @param[in] JsonValue JSON value +**/ +VOID +EFIAPI +JsonDecreaseReference ( + IN EDKII_JSON_VALUE JsonValue + ) +{ + json_decref (JsonValue); +} + +/** + The reference count is used to track whether a value is still in use or not. + When a value is created, it's reference count is set to 1. + If a reference to a value is kept (e.g. a value is stored somewhere for later use), + its reference count is incremented. + + This function increment the reference count of json if it's not NULL. + Returns EDKII_JSON_VALUE. + + @param[in] JsonValue JSON value + @retval EDKII_JSON_VALUE of itself +**/ +EDKII_JSON_VALUE +EFIAPI +JsonIncreaseReference ( + IN EDKII_JSON_VALUE JsonValue + ) +{ + return json_incref (JsonValue); +} + +/** + Returns an opaque iterator which can be used to iterate over all key-value pairs + in object, or NULL if object is empty. + + @param[in] JsonValue JSON value + @retval Iterator pointer +**/ +VOID * +EFIAPI +JsonObjectIterator ( + IN EDKII_JSON_VALUE JsonValue + ) +{ + return json_object_iter (JsonValue); +} + +/** + Extract the associated value from iterator. + + @param[in] Iterator Iterator pointer + @retval EDKII_JSON_VALUE +**/ +EDKII_JSON_VALUE +EFIAPI +JsonObjectIteratorValue ( + IN VOID *Iterator + ) +{ + return json_object_iter_value(Iterator); +} + +/** + Returns an iterator pointing to the next key-value pair in object after iter, + or NULL if the whole object has been iterated through. + + @param[in] JsonValue JSON value + @param[in] Iterator Iterator pointer + @retval Iterator pointer +**/ +VOID * +EFIAPI +JsonObjectIteratorNext ( + IN EDKII_JSON_VALUE JsonValue, + IN VOID *Iterator + ) +{ + return json_object_iter_next(JsonValue, Iterator); +} + +/** + Returns the key of iterator pointing. + + @param[in] Iterator Iterator pointer + @retval Key +**/ +CHAR8 * +EFIAPI +JsonObjectIteratorKey ( + IN VOID *Iterator +) +{ + return (CHAR8 *)json_object_iter_key(Iterator); +} + +/** + Returns the pointer of iterator by key. + + @param[in] Key The key of interator pointer. + @retval Pointer to interator +**/ +VOID * +EFIAPI +JsonObjectKeyToIterator ( + IN CHAR8 *Key +) +{ + return json_object_key_to_iter(Key); +} + +/** + Returns the json type of this json value. + + @param[in] JsonValue JSON value + @retval JSON type returned +**/ +EDKII_JSON_TYPE +EFIAPI +JsonGetType ( + IN EDKII_JSON_VALUE JsonValue + ) +{ + return ((json_t *)JsonValue)->type; +} diff --git a/CdeEmuPkg/RedfishPkg/Library/JsonLib/JsonLib.inf b/CdeEmuPkg/RedfishPkg/Library/JsonLib/JsonLib.inf new file mode 100644 index 00000000000..bcc93550c86 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/JsonLib/JsonLib.inf @@ -0,0 +1,87 @@ +## @file +# Thirty party Jansson library for JSON operations. +# +# 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 = 0x0001001b + BASE_NAME = JsonLib + FILE_GUID = F5E36815-305A-4C5A-9D75-4F2149E45255 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = JsonLib|DXE_DRIVER UEFI_APPLICATION UEFI_DRIVER + +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64 +# + +[Sources] + # + # Below are the source code of third + # party jansson library. + # + jansson/src/dump.c + jansson/src/error.c + jansson/src/hashtable.c + jansson/src/hashtable_seed.c + jansson/src/memory.c + jansson/src/pack_unpack.c + jansson/src/strbuffer.c + jansson/src/strconv.c + jansson/src/utf.c + jansson/src/value.c + jansson/src/version.c + # + # Below are the source of edk2 JsonLib. + # + JsonLib.c + jansson_config.h + jansson_private_config.h + # + # Below is the source code override to fix the build issue. + # Add code in load.c to conditionally use stdin according + # to HAVE_UNISTD_H macro. The PR is submitted to jansson + # open source community. + # https://github.com/akheron/jansson/pull/558 + # + load.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + Ucs2Utf8Lib + RedfishCrtLib + DebugLib + MemoryAllocationLib + PrintLib + UefiRuntimeServicesTableLib + UefiLib + +[BuildOptions] + # + # Disables the following Visual Studio compiler warnings + # so we do not break the build with /WX option: + # C4090: 'function' : different 'const' qualifiers + # C4244: conversion from type1 to type2, possible loss of data + # C4334: 32-bit shift implicitly converted to 64-bit + # C4204: nonstandard extension used: non-constant aggregate initializer + # C4706: assignment within conditional expression + # + # Define macro HAVE_CONFIG_H to include jansson_private_config.h to build. + # Undefined _WIN32, WIN64, _MSC_VER macros + # On GCC, no error on the unused-function and unused-but-set-variable. + # + MSFT:*_*_X64_CC_FLAGS = /wd4204 /wd4244 /wd4090 /wd4334 /wd4706 /DHAVE_CONFIG_H=1 /U_WIN32 /UWIN64 /U_MSC_VER + MSFT:*_*_IA32_CC_FLAGS = /wd4204 /wd4244 /wd4090 /wd4706 /DHAVE_CONFIG_H=1 /U_WIN32 /UWIN64 /U_MSC_VER + GCC:*_*_*_CC_FLAGS = -Wno-unused-function -Wno-unused-but-set-variable + diff --git a/CdeEmuPkg/RedfishPkg/Library/JsonLib/Readme.rst b/CdeEmuPkg/RedfishPkg/Library/JsonLib/Readme.rst new file mode 100644 index 00000000000..75e7cc437fd --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/JsonLib/Readme.rst @@ -0,0 +1,35 @@ +============================================================================= + Introduction +============================================================================= + Jansson is a C library for encoding, decoding and manipulating JSON data. +Its main features and design principles are: + + - Simple and intuitive API and data model + - Comprehensive documentation + - No dependencies on other libraries + - Full Unicode support (UTF-8) + - Extensive test suite + + Jansson is licensed under the MIT license(refer to ReadMe.rst under edk2). +It is used in production and its API is stable. It works on numerous +platforms, including numerous Unix like systems and Windows. It's suitable +for use on any system, including desktop, server, and small embedded systems. + + In UEFI/EDKII environment, Redfish project consumes jansson to achieve JSON +operations. + +* Jansson version on edk2: 2.13.1, API reference is on the below URL, + https://jansson.readthedocs.io/en/2.13/apiref.html + +* EDKII jansson library wrapper: + - JsonLib.h: + This is the denifitions of EDKII JSON APIs which are mapped to + jannson funcitons accordingly. + +*Known issue: + Build fail with jansson/src/load.c, add code in load.c to conditionally + use stdin according to HAVE_UNISTD_H macro. The PR is submitted to + jansson open source community. + https://github.com/akheron/jansson/pull/558 + + diff --git a/CdeEmuPkg/RedfishPkg/Library/JsonLib/jansson b/CdeEmuPkg/RedfishPkg/Library/JsonLib/jansson new file mode 160000 index 00000000000..e9ebfa7e77a --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/JsonLib/jansson @@ -0,0 +1 @@ +Subproject commit e9ebfa7e77a6bee77df44e096b100e7131044059 diff --git a/CdeEmuPkg/RedfishPkg/Library/JsonLib/jansson_config.h b/CdeEmuPkg/RedfishPkg/Library/JsonLib/jansson_config.h new file mode 100644 index 00000000000..09cc2992fed --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/JsonLib/jansson_config.h @@ -0,0 +1,41 @@ +/** @file This is the configuration file for building jansson library. + + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + **/ + +#ifndef JANSSON_CONFIG_H_ +#define JANSSON_CONFIG_H_ + +/// +/// We don't support inline JSON on edk2 +/// +#define JSON_INLINE + +/// +/// We support long long on edk2 +/// +#define JSON_INTEGER_IS_LONG_LONG 1 + +/// +/// We don't support locale on edk2 +/// +#define JSON_HAVE_LOCALECONV 0 + +/// +/// We don't support atomic builtins on edk2 +/// +#define JSON_HAVE_ATOMIC_BUILTINS 0 + +/// +/// We don't support sync builtins on edk2 +/// +#define JSON_HAVE_SYNC_BUILTINS 0 + +/// +/// Mzximum deepth is set to 2048 +/// +#define JSON_PARSER_MAX_DEPTH 2048 + +#endif diff --git a/CdeEmuPkg/RedfishPkg/Library/JsonLib/jansson_private_config.h b/CdeEmuPkg/RedfishPkg/Library/JsonLib/jansson_private_config.h new file mode 100644 index 00000000000..893a3c76c86 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/JsonLib/jansson_private_config.h @@ -0,0 +1,19 @@ +/** @file + Jansson private configurations for UEFI support. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef JANSSON_PRIVATE_CONFIG_H_ +#define JANSSON_PRIVATE_CONFIG_H_ + +#define HAVE_SYS_TIME_H 1 +#define HAVE_SYS_TYPES_H 1 + +#define INITIAL_HASHTABLE_ORDER 3 + +#endif diff --git a/CdeEmuPkg/RedfishPkg/Library/JsonLib/load.c b/CdeEmuPkg/RedfishPkg/Library/JsonLib/load.c new file mode 100644 index 00000000000..41d6a034779 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/JsonLib/load.c @@ -0,0 +1,1111 @@ +/* + * Copyright (c) 2009-2016 Petri Lehtinen + * + * Jansson is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent AND MIT + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include "jansson_private.h" + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "jansson.h" +#include "strbuffer.h" +#include "utf.h" + +#define STREAM_STATE_OK 0 +#define STREAM_STATE_EOF -1 +#define STREAM_STATE_ERROR -2 + +#define TOKEN_INVALID -1 +#define TOKEN_EOF 0 +#define TOKEN_STRING 256 +#define TOKEN_INTEGER 257 +#define TOKEN_REAL 258 +#define TOKEN_TRUE 259 +#define TOKEN_FALSE 260 +#define TOKEN_NULL 261 + +/* Locale independent versions of isxxx() functions */ +#define l_isupper(c) ('A' <= (c) && (c) <= 'Z') +#define l_islower(c) ('a' <= (c) && (c) <= 'z') +#define l_isalpha(c) (l_isupper(c) || l_islower(c)) +#define l_isdigit(c) ('0' <= (c) && (c) <= '9') +#define l_isxdigit(c) \ + (l_isdigit(c) || ('A' <= (c) && (c) <= 'F') || ('a' <= (c) && (c) <= 'f')) + +/* Read one byte from stream, convert to unsigned char, then int, and + return. return EOF on end of file. This corresponds to the + behaviour of fgetc(). */ +typedef int (*get_func)(void *data); + +typedef struct { + get_func get; + void *data; + char buffer[5]; + size_t buffer_pos; + int state; + int line; + int column, last_column; + size_t position; +} stream_t; + +typedef struct { + stream_t stream; + strbuffer_t saved_text; + size_t flags; + size_t depth; + int token; + union { + struct { + char *val; + size_t len; + } string; + json_int_t integer; + double real; + } value; +} lex_t; + +#define stream_to_lex(stream) container_of(stream, lex_t, stream) + +/*** error reporting ***/ + +static void error_set(json_error_t *error, const lex_t *lex, enum json_error_code code, + const char *msg, ...) { + va_list ap; + char msg_text[JSON_ERROR_TEXT_LENGTH]; + char msg_with_context[JSON_ERROR_TEXT_LENGTH]; + + int line = -1, col = -1; + size_t pos = 0; + const char *result = msg_text; + + if (!error) + return; + + va_start(ap, msg); + vsnprintf(msg_text, JSON_ERROR_TEXT_LENGTH, msg, ap); + msg_text[JSON_ERROR_TEXT_LENGTH - 1] = '\0'; + va_end(ap); + + if (lex) { + const char *saved_text = strbuffer_value(&lex->saved_text); + + line = lex->stream.line; + col = lex->stream.column; + pos = lex->stream.position; + + if (saved_text && saved_text[0]) { + if (lex->saved_text.length <= 20) { + snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near '%s'", + msg_text, saved_text); + msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0'; + result = msg_with_context; + } + } else { + if (code == json_error_invalid_syntax) { + /* More specific error code for premature end of file. */ + code = json_error_premature_end_of_input; + } + if (lex->stream.state == STREAM_STATE_ERROR) { + /* No context for UTF-8 decoding errors */ + result = msg_text; + } else { + snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near end of file", + msg_text); + msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0'; + result = msg_with_context; + } + } + } + + jsonp_error_set(error, line, col, pos, code, "%s", result); +} + +/*** lexical analyzer ***/ + +static void stream_init(stream_t *stream, get_func get, void *data) { + stream->get = get; + stream->data = data; + stream->buffer[0] = '\0'; + stream->buffer_pos = 0; + + stream->state = STREAM_STATE_OK; + stream->line = 1; + stream->column = 0; + stream->position = 0; +} + +static int stream_get(stream_t *stream, json_error_t *error) { + int c; + + if (stream->state != STREAM_STATE_OK) + return stream->state; + + if (!stream->buffer[stream->buffer_pos]) { + c = stream->get(stream->data); + if (c == EOF) { + stream->state = STREAM_STATE_EOF; + return STREAM_STATE_EOF; + } + + stream->buffer[0] = c; + stream->buffer_pos = 0; + + if (0x80 <= c && c <= 0xFF) { + /* multi-byte UTF-8 sequence */ + size_t i, count; + + count = utf8_check_first(c); + if (!count) + goto out; + + assert(count >= 2); + + for (i = 1; i < count; i++) + stream->buffer[i] = stream->get(stream->data); + + if (!utf8_check_full(stream->buffer, count, NULL)) + goto out; + + stream->buffer[count] = '\0'; + } else + stream->buffer[1] = '\0'; + } + + c = stream->buffer[stream->buffer_pos++]; + + stream->position++; + if (c == '\n') { + stream->line++; + stream->last_column = stream->column; + stream->column = 0; + } else if (utf8_check_first(c)) { + /* track the Unicode character column, so increment only if + this is the first character of a UTF-8 sequence */ + stream->column++; + } + + return c; + +out: + stream->state = STREAM_STATE_ERROR; + error_set(error, stream_to_lex(stream), json_error_invalid_utf8, + "unable to decode byte 0x%x", c); + return STREAM_STATE_ERROR; +} + +static void stream_unget(stream_t *stream, int c) { + if (c == STREAM_STATE_EOF || c == STREAM_STATE_ERROR) + return; + + stream->position--; + if (c == '\n') { + stream->line--; + stream->column = stream->last_column; + } else if (utf8_check_first(c)) + stream->column--; + + assert(stream->buffer_pos > 0); + stream->buffer_pos--; + assert(stream->buffer[stream->buffer_pos] == c); +} + +static int lex_get(lex_t *lex, json_error_t *error) { + return stream_get(&lex->stream, error); +} + +static void lex_save(lex_t *lex, int c) { strbuffer_append_byte(&lex->saved_text, c); } + +static int lex_get_save(lex_t *lex, json_error_t *error) { + int c = stream_get(&lex->stream, error); + if (c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) + lex_save(lex, c); + return c; +} + +static void lex_unget(lex_t *lex, int c) { stream_unget(&lex->stream, c); } + +static void lex_unget_unsave(lex_t *lex, int c) { + if (c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) { +/* Since we treat warnings as errors, when assertions are turned + * off the "d" variable would be set but never used. Which is + * treated as an error by GCC. + */ +#ifndef NDEBUG + char d; +#endif + stream_unget(&lex->stream, c); +#ifndef NDEBUG + d = +#endif + strbuffer_pop(&lex->saved_text); + assert(c == d); + } +} + +static void lex_save_cached(lex_t *lex) { + while (lex->stream.buffer[lex->stream.buffer_pos] != '\0') { + lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]); + lex->stream.buffer_pos++; + lex->stream.position++; + } +} + +static void lex_free_string(lex_t *lex) { + jsonp_free(lex->value.string.val); + lex->value.string.val = NULL; + lex->value.string.len = 0; +} + +/* assumes that str points to 'u' plus at least 4 valid hex digits */ +static int32_t decode_unicode_escape(const char *str) { + int i; + int32_t value = 0; + + assert(str[0] == 'u'); + + for (i = 1; i <= 4; i++) { + char c = str[i]; + value <<= 4; + if (l_isdigit(c)) + value += c - '0'; + else if (l_islower(c)) + value += c - 'a' + 10; + else if (l_isupper(c)) + value += c - 'A' + 10; + else + return -1; + } + + return value; +} + +static void lex_scan_string(lex_t *lex, json_error_t *error) { + int c; + const char *p; + char *t; + int i; + + lex->value.string.val = NULL; + lex->token = TOKEN_INVALID; + + c = lex_get_save(lex, error); + + while (c != '"') { + if (c == STREAM_STATE_ERROR) + goto out; + + else if (c == STREAM_STATE_EOF) { + error_set(error, lex, json_error_premature_end_of_input, + "premature end of input"); + goto out; + } + + else if (0 <= c && c <= 0x1F) { + /* control character */ + lex_unget_unsave(lex, c); + if (c == '\n') + error_set(error, lex, json_error_invalid_syntax, "unexpected newline"); + else + error_set(error, lex, json_error_invalid_syntax, "control character 0x%x", + c); + goto out; + } + + else if (c == '\\') { + c = lex_get_save(lex, error); + if (c == 'u') { + c = lex_get_save(lex, error); + for (i = 0; i < 4; i++) { + if (!l_isxdigit(c)) { + error_set(error, lex, json_error_invalid_syntax, + "invalid escape"); + goto out; + } + c = lex_get_save(lex, error); + } + } else if (c == '"' || c == '\\' || c == '/' || c == 'b' || c == 'f' || + c == 'n' || c == 'r' || c == 't') + c = lex_get_save(lex, error); + else { + error_set(error, lex, json_error_invalid_syntax, "invalid escape"); + goto out; + } + } else + c = lex_get_save(lex, error); + } + + /* the actual value is at most of the same length as the source + string, because: + - shortcut escapes (e.g. "\t") (length 2) are converted to 1 byte + - a single \uXXXX escape (length 6) is converted to at most 3 bytes + - two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair + are converted to 4 bytes + */ + t = jsonp_malloc(lex->saved_text.length + 1); + if (!t) { + /* this is not very nice, since TOKEN_INVALID is returned */ + goto out; + } + lex->value.string.val = t; + + /* + 1 to skip the " */ + p = strbuffer_value(&lex->saved_text) + 1; + + while (*p != '"') { + if (*p == '\\') { + p++; + if (*p == 'u') { + size_t length; + int32_t value; + + value = decode_unicode_escape(p); + if (value < 0) { + error_set(error, lex, json_error_invalid_syntax, + "invalid Unicode escape '%.6s'", p - 1); + goto out; + } + p += 5; + + if (0xD800 <= value && value <= 0xDBFF) { + /* surrogate pair */ + if (*p == '\\' && *(p + 1) == 'u') { + int32_t value2 = decode_unicode_escape(++p); + if (value2 < 0) { + error_set(error, lex, json_error_invalid_syntax, + "invalid Unicode escape '%.6s'", p - 1); + goto out; + } + p += 5; + + if (0xDC00 <= value2 && value2 <= 0xDFFF) { + /* valid second surrogate */ + value = + ((value - 0xD800) << 10) + (value2 - 0xDC00) + 0x10000; + } else { + /* invalid second surrogate */ + error_set(error, lex, json_error_invalid_syntax, + "invalid Unicode '\\u%04X\\u%04X'", value, value2); + goto out; + } + } else { + /* no second surrogate */ + error_set(error, lex, json_error_invalid_syntax, + "invalid Unicode '\\u%04X'", value); + goto out; + } + } else if (0xDC00 <= value && value <= 0xDFFF) { + error_set(error, lex, json_error_invalid_syntax, + "invalid Unicode '\\u%04X'", value); + goto out; + } + + if (utf8_encode(value, t, &length)) + assert(0); + t += length; + } else { + switch (*p) { + case '"': + case '\\': + case '/': + *t = *p; + break; + case 'b': + *t = '\b'; + break; + case 'f': + *t = '\f'; + break; + case 'n': + *t = '\n'; + break; + case 'r': + *t = '\r'; + break; + case 't': + *t = '\t'; + break; + default: + assert(0); + } + t++; + p++; + } + } else + *(t++) = *(p++); + } + *t = '\0'; + lex->value.string.len = t - lex->value.string.val; + lex->token = TOKEN_STRING; + return; + +out: + lex_free_string(lex); +} + +#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */ +#if JSON_INTEGER_IS_LONG_LONG +#ifdef _MSC_VER /* Microsoft Visual Studio */ +#define json_strtoint _strtoi64 +#else +#define json_strtoint strtoll +#endif +#else +#define json_strtoint strtol +#endif +#endif + +static int lex_scan_number(lex_t *lex, int c, json_error_t *error) { + const char *saved_text; + char *end; + double doubleval; + + lex->token = TOKEN_INVALID; + + if (c == '-') + c = lex_get_save(lex, error); + + if (c == '0') { + c = lex_get_save(lex, error); + if (l_isdigit(c)) { + lex_unget_unsave(lex, c); + goto out; + } + } else if (l_isdigit(c)) { + do + c = lex_get_save(lex, error); + while (l_isdigit(c)); + } else { + lex_unget_unsave(lex, c); + goto out; + } + + if (!(lex->flags & JSON_DECODE_INT_AS_REAL) && c != '.' && c != 'E' && c != 'e') { + json_int_t intval; + + lex_unget_unsave(lex, c); + + saved_text = strbuffer_value(&lex->saved_text); + + errno = 0; + intval = json_strtoint(saved_text, &end, 10); + if (errno == ERANGE) { + if (intval < 0) + error_set(error, lex, json_error_numeric_overflow, + "too big negative integer"); + else + error_set(error, lex, json_error_numeric_overflow, "too big integer"); + goto out; + } + + assert(end == saved_text + lex->saved_text.length); + + lex->token = TOKEN_INTEGER; + lex->value.integer = intval; + return 0; + } + + if (c == '.') { + c = lex_get(lex, error); + if (!l_isdigit(c)) { + lex_unget(lex, c); + goto out; + } + lex_save(lex, c); + + do + c = lex_get_save(lex, error); + while (l_isdigit(c)); + } + + if (c == 'E' || c == 'e') { + c = lex_get_save(lex, error); + if (c == '+' || c == '-') + c = lex_get_save(lex, error); + + if (!l_isdigit(c)) { + lex_unget_unsave(lex, c); + goto out; + } + + do + c = lex_get_save(lex, error); + while (l_isdigit(c)); + } + + lex_unget_unsave(lex, c); + + if (jsonp_strtod(&lex->saved_text, &doubleval)) { + error_set(error, lex, json_error_numeric_overflow, "real number overflow"); + goto out; + } + + lex->token = TOKEN_REAL; + lex->value.real = doubleval; + return 0; + +out: + return -1; +} + +static int lex_scan(lex_t *lex, json_error_t *error) { + int c; + + strbuffer_clear(&lex->saved_text); + + if (lex->token == TOKEN_STRING) + lex_free_string(lex); + + do + c = lex_get(lex, error); + while (c == ' ' || c == '\t' || c == '\n' || c == '\r'); + + if (c == STREAM_STATE_EOF) { + lex->token = TOKEN_EOF; + goto out; + } + + if (c == STREAM_STATE_ERROR) { + lex->token = TOKEN_INVALID; + goto out; + } + + lex_save(lex, c); + + if (c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',') + lex->token = c; + + else if (c == '"') + lex_scan_string(lex, error); + + else if (l_isdigit(c) || c == '-') { + if (lex_scan_number(lex, c, error)) + goto out; + } + + else if (l_isalpha(c)) { + /* eat up the whole identifier for clearer error messages */ + const char *saved_text; + + do + c = lex_get_save(lex, error); + while (l_isalpha(c)); + lex_unget_unsave(lex, c); + + saved_text = strbuffer_value(&lex->saved_text); + + if (strcmp(saved_text, "true") == 0) + lex->token = TOKEN_TRUE; + else if (strcmp(saved_text, "false") == 0) + lex->token = TOKEN_FALSE; + else if (strcmp(saved_text, "null") == 0) + lex->token = TOKEN_NULL; + else + lex->token = TOKEN_INVALID; + } + + else { + /* save the rest of the input UTF-8 sequence to get an error + message of valid UTF-8 */ + lex_save_cached(lex); + lex->token = TOKEN_INVALID; + } + +out: + return lex->token; +} + +static char *lex_steal_string(lex_t *lex, size_t *out_len) { + char *result = NULL; + if (lex->token == TOKEN_STRING) { + result = lex->value.string.val; + *out_len = lex->value.string.len; + lex->value.string.val = NULL; + lex->value.string.len = 0; + } + return result; +} + +static int lex_init(lex_t *lex, get_func get, size_t flags, void *data) { + stream_init(&lex->stream, get, data); + if (strbuffer_init(&lex->saved_text)) + return -1; + + lex->flags = flags; + lex->token = TOKEN_INVALID; + return 0; +} + +static void lex_close(lex_t *lex) { + if (lex->token == TOKEN_STRING) + lex_free_string(lex); + strbuffer_close(&lex->saved_text); +} + +/*** parser ***/ + +static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error); + +static json_t *parse_object(lex_t *lex, size_t flags, json_error_t *error) { + json_t *object = json_object(); + if (!object) + return NULL; + + lex_scan(lex, error); + if (lex->token == '}') + return object; + + while (1) { + char *key; + size_t len; + json_t *value; + + if (lex->token != TOKEN_STRING) { + error_set(error, lex, json_error_invalid_syntax, "string or '}' expected"); + goto error; + } + + key = lex_steal_string(lex, &len); + if (!key) + return NULL; + if (memchr(key, '\0', len)) { + jsonp_free(key); + error_set(error, lex, json_error_null_byte_in_key, + "NUL byte in object key not supported"); + goto error; + } + + if (flags & JSON_REJECT_DUPLICATES) { + if (json_object_get(object, key)) { + jsonp_free(key); + error_set(error, lex, json_error_duplicate_key, "duplicate object key"); + goto error; + } + } + + lex_scan(lex, error); + if (lex->token != ':') { + jsonp_free(key); + error_set(error, lex, json_error_invalid_syntax, "':' expected"); + goto error; + } + + lex_scan(lex, error); + value = parse_value(lex, flags, error); + if (!value) { + jsonp_free(key); + goto error; + } + + if (json_object_set_new_nocheck(object, key, value)) { + jsonp_free(key); + goto error; + } + + jsonp_free(key); + + lex_scan(lex, error); + if (lex->token != ',') + break; + + lex_scan(lex, error); + } + + if (lex->token != '}') { + error_set(error, lex, json_error_invalid_syntax, "'}' expected"); + goto error; + } + + return object; + +error: + json_decref(object); + return NULL; +} + +static json_t *parse_array(lex_t *lex, size_t flags, json_error_t *error) { + json_t *array = json_array(); + if (!array) + return NULL; + + lex_scan(lex, error); + if (lex->token == ']') + return array; + + while (lex->token) { + json_t *elem = parse_value(lex, flags, error); + if (!elem) + goto error; + + if (json_array_append_new(array, elem)) { + goto error; + } + + lex_scan(lex, error); + if (lex->token != ',') + break; + + lex_scan(lex, error); + } + + if (lex->token != ']') { + error_set(error, lex, json_error_invalid_syntax, "']' expected"); + goto error; + } + + return array; + +error: + json_decref(array); + return NULL; +} + +static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error) { + json_t *json; + + lex->depth++; + if (lex->depth > JSON_PARSER_MAX_DEPTH) { + error_set(error, lex, json_error_stack_overflow, "maximum parsing depth reached"); + return NULL; + } + + switch (lex->token) { + case TOKEN_STRING: { + const char *value = lex->value.string.val; + size_t len = lex->value.string.len; + + if (!(flags & JSON_ALLOW_NUL)) { + if (memchr(value, '\0', len)) { + error_set(error, lex, json_error_null_character, + "\\u0000 is not allowed without JSON_ALLOW_NUL"); + return NULL; + } + } + + json = jsonp_stringn_nocheck_own(value, len); + lex->value.string.val = NULL; + lex->value.string.len = 0; + break; + } + + case TOKEN_INTEGER: { + json = json_integer(lex->value.integer); + break; + } + + case TOKEN_REAL: { + json = json_real(lex->value.real); + break; + } + + case TOKEN_TRUE: + json = json_true(); + break; + + case TOKEN_FALSE: + json = json_false(); + break; + + case TOKEN_NULL: + json = json_null(); + break; + + case '{': + json = parse_object(lex, flags, error); + break; + + case '[': + json = parse_array(lex, flags, error); + break; + + case TOKEN_INVALID: + error_set(error, lex, json_error_invalid_syntax, "invalid token"); + return NULL; + + default: + error_set(error, lex, json_error_invalid_syntax, "unexpected token"); + return NULL; + } + + if (!json) + return NULL; + + lex->depth--; + return json; +} + +static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error) { + json_t *result; + + lex->depth = 0; + + lex_scan(lex, error); + if (!(flags & JSON_DECODE_ANY)) { + if (lex->token != '[' && lex->token != '{') { + error_set(error, lex, json_error_invalid_syntax, "'[' or '{' expected"); + return NULL; + } + } + + result = parse_value(lex, flags, error); + if (!result) + return NULL; + + if (!(flags & JSON_DISABLE_EOF_CHECK)) { + lex_scan(lex, error); + if (lex->token != TOKEN_EOF) { + error_set(error, lex, json_error_end_of_input_expected, + "end of file expected"); + json_decref(result); + return NULL; + } + } + + if (error) { + /* Save the position even though there was no error */ + error->position = (int)lex->stream.position; + } + + return result; +} + +typedef struct { + const char *data; + size_t pos; +} string_data_t; + +static int string_get(void *data) { + char c; + string_data_t *stream = (string_data_t *)data; + c = stream->data[stream->pos]; + if (c == '\0') + return EOF; + else { + stream->pos++; + return (unsigned char)c; + } +} + +json_t *json_loads(const char *string, size_t flags, json_error_t *error) { + lex_t lex; + json_t *result; + string_data_t stream_data; + + jsonp_error_init(error, ""); + + if (string == NULL) { + error_set(error, NULL, json_error_invalid_argument, "wrong arguments"); + return NULL; + } + + stream_data.data = string; + stream_data.pos = 0; + + if (lex_init(&lex, string_get, flags, (void *)&stream_data)) + return NULL; + + result = parse_json(&lex, flags, error); + + lex_close(&lex); + return result; +} + +typedef struct { + const char *data; + size_t len; + size_t pos; +} buffer_data_t; + +static int buffer_get(void *data) { + char c; + buffer_data_t *stream = data; + if (stream->pos >= stream->len) + return EOF; + + c = stream->data[stream->pos]; + stream->pos++; + return (unsigned char)c; +} + +json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error) { + lex_t lex; + json_t *result; + buffer_data_t stream_data; + + jsonp_error_init(error, ""); + + if (buffer == NULL) { + error_set(error, NULL, json_error_invalid_argument, "wrong arguments"); + return NULL; + } + + stream_data.data = buffer; + stream_data.pos = 0; + stream_data.len = buflen; + + if (lex_init(&lex, buffer_get, flags, (void *)&stream_data)) + return NULL; + + result = parse_json(&lex, flags, error); + + lex_close(&lex); + return result; +} + +json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) { + lex_t lex; + const char *source; + json_t *result; +#ifdef HAVE_UNISTD_H + if (input == stdin) + source = ""; + else +#endif + source = ""; + + jsonp_error_init(error, source); + + if (input == NULL) { + error_set(error, NULL, json_error_invalid_argument, "wrong arguments"); + return NULL; + } + + if (lex_init(&lex, (get_func)fgetc, flags, input)) + return NULL; + + result = parse_json(&lex, flags, error); + + lex_close(&lex); + return result; +} + +static int fd_get_func(int *fd) { +#ifdef HAVE_UNISTD_H + uint8_t c; + if (read(*fd, &c, 1) == 1) + return c; +#endif + return EOF; +} + +json_t *json_loadfd(int input, size_t flags, json_error_t *error) { + lex_t lex; + const char *source; + json_t *result; + +#ifdef HAVE_UNISTD_H + if (input == STDIN_FILENO) + source = ""; + else +#endif + source = ""; + + jsonp_error_init(error, source); + + if (input < 0) { + error_set(error, NULL, json_error_invalid_argument, "wrong arguments"); + return NULL; + } + + if (lex_init(&lex, (get_func)fd_get_func, flags, &input)) + return NULL; + + result = parse_json(&lex, flags, error); + + lex_close(&lex); + return result; +} + +json_t *json_load_file(const char *path, size_t flags, json_error_t *error) { + json_t *result; + FILE *fp; + + jsonp_error_init(error, path); + + if (path == NULL) { + error_set(error, NULL, json_error_invalid_argument, "wrong arguments"); + return NULL; + } + + fp = fopen(path, "rb"); + if (!fp) { + error_set(error, NULL, json_error_cannot_open_file, "unable to open %s: %s", path, + strerror(errno)); + return NULL; + } + + result = json_loadf(fp, flags, error); + + fclose(fp); + return result; +} + +#define MAX_BUF_LEN 1024 + +typedef struct { + char data[MAX_BUF_LEN]; + size_t len; + size_t pos; + json_load_callback_t callback; + void *arg; +} callback_data_t; + +static int callback_get(void *data) { + char c; + callback_data_t *stream = data; + + if (stream->pos >= stream->len) { + stream->pos = 0; + stream->len = stream->callback(stream->data, MAX_BUF_LEN, stream->arg); + if (stream->len == 0 || stream->len == (size_t)-1) + return EOF; + } + + c = stream->data[stream->pos]; + stream->pos++; + return (unsigned char)c; +} + +json_t *json_load_callback(json_load_callback_t callback, void *arg, size_t flags, + json_error_t *error) { + lex_t lex; + json_t *result; + + callback_data_t stream_data; + + memset(&stream_data, 0, sizeof(stream_data)); + stream_data.callback = callback; + stream_data.arg = arg; + + jsonp_error_init(error, ""); + + if (callback == NULL) { + error_set(error, NULL, json_error_invalid_argument, "wrong arguments"); + return NULL; + } + + if (lex_init(&lex, (get_func)callback_get, flags, &stream_data)) + return NULL; + + result = parse_json(&lex, flags, error); + + lex_close(&lex); + return result; +} diff --git a/CdeEmuPkg/RedfishPkg/Library/PlatformCredentialLibNull/PlatformCredentialLibNull.c b/CdeEmuPkg/RedfishPkg/Library/PlatformCredentialLibNull/PlatformCredentialLibNull.c new file mode 100644 index 00000000000..19fe2e20210 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/PlatformCredentialLibNull/PlatformCredentialLibNull.c @@ -0,0 +1,101 @@ +/** @file + NULL instace of RedfishPlatformCredentialLib + + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +/** + Notification of Exit Boot Service. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL. +**/ +VOID +EFIAPI +LibCredentialExitBootServicesNotify ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This +) +{ + return; +} + +/** + Notification of End of DXe. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL. +**/ +VOID +EFIAPI +LibCredentialEndOfDxeNotify ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This +) +{ + return; +} + +/** + Retrieve platform's Redfish authentication information. + + This functions returns the Redfish authentication method together with the user Id and + password. + - For AuthMethodNone, the UserId and Password could be used for HTTP header authentication + as defined by RFC7235. + - For AuthMethodRedfishSession, the UserId and Password could be used for Redfish + session login as defined by Redfish API specification (DSP0266). + + Callers are responsible for and freeing the returned string storage. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + @param[out] AuthMethod Type of Redfish authentication method. + @param[out] UserId The pointer to store the returned UserId string. + @param[out] Password The pointer to store the returned Password string. + + @retval EFI_SUCCESS Get the authentication information successfully. + @retval EFI_ACCESS_DENIED SecureBoot is disabled after EndOfDxe. + @retval EFI_INVALID_PARAMETER This or AuthMethod or UserId or Password is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough memory resources. + @retval EFI_UNSUPPORTED Unsupported authentication method is found. + +**/ +EFI_STATUS +EFIAPI +LibCredentialGetAuthInfo ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, + OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod, + OUT CHAR8 **UserId, + OUT CHAR8 **Password +) +{ + return EFI_UNSUPPORTED; +} + +/** + Notify the Redfish service provide to stop provide configuration service to this platform. + + This function should be called when the platfrom is about to leave the safe environment. + It will notify the Redfish service provider to abort all logined session, and prohibit + further login with original auth info. GetAuthInfo() will return EFI_UNSUPPORTED once this + function is returned. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + @param[in] ServiceStopType Reason of stopping Redfish service. + + @retval EFI_SUCCESS Service has been stoped successfully. + @retval EFI_INVALID_PARAMETER This is NULL or given the worng ServiceStopType. + @retval EFI_UNSUPPORTED Not support to stop Redfish service. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +LibStopRedfishService ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, + IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType + ) +{ + return EFI_UNSUPPORTED; +} + diff --git a/CdeEmuPkg/RedfishPkg/Library/PlatformCredentialLibNull/PlatformCredentialLibNull.inf b/CdeEmuPkg/RedfishPkg/Library/PlatformCredentialLibNull/PlatformCredentialLibNull.inf new file mode 100644 index 00000000000..ddad90c042b --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/PlatformCredentialLibNull/PlatformCredentialLibNull.inf @@ -0,0 +1,30 @@ +## @file +# NULL instance of RedfishPlatformCredentialLib +# +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001000b + BASE_NAME = RedfishPlatformCredentialLibNull + FILE_GUID = CA3BD843-0BDD-4EE0-A38A-B45CA663114F + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = RedfishPlatformCredentialLib + +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64 +# + +[Sources] + PlatformCredentialLibNull.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + + diff --git a/CdeEmuPkg/RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.c b/CdeEmuPkg/RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.c new file mode 100644 index 00000000000..598c7f1ed3a --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.c @@ -0,0 +1,52 @@ +/** @file + NULL instace of RedfishPlatformHostInterfaceLib + + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include + +/** + Get platform Redfish host interface device descriptor. + + @param[in] DeviceType Pointer to retrieve device type. + @param[out] DeviceDescriptor Pointer to retrieve REDFISH_INTERFACE_DATA, caller has to free + this memory using FreePool(). + + @retval EFI_NOT_FOUND No Redfish host interface descriptor provided on this platform. + +**/ +EFI_STATUS +RedfishPlatformHostInterfaceDeviceDescriptor ( + IN UINT8 *DeviceType, + OUT REDFISH_INTERFACE_DATA **DeviceDescriptor +) +{ + return EFI_NOT_FOUND; +} +/** + Get platform Redfish host interface protocol data. + Caller should pass NULL in ProtocolRecord to retrive the first protocol record. + Then continuously pass previous ProtocolRecord for retrieving the next ProtocolRecord. + + @param[in, out] ProtocolRecord Pointer to retrieve the first or the next protocol record. + caller has to free the new protocol record returned from + this function using FreePool(). + @param[in] IndexOfProtocolData The index of protocol data. + + @retval EFI_NOT_FOUND No more protocol records. + +**/ +EFI_STATUS +RedfishPlatformHostInterfaceProtocolData ( + IN OUT MC_HOST_INTERFACE_PROTOCOL_RECORD **ProtocolRecord, + IN UINT8 IndexOfProtocolData +) +{ + return EFI_NOT_FOUND; +} diff --git a/CdeEmuPkg/RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.inf b/CdeEmuPkg/RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.inf new file mode 100644 index 00000000000..fe60ad49fc9 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.inf @@ -0,0 +1,33 @@ +## @file +# NULL instance of RedfishPlatformHostInterfaceLib +# +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001000b + BASE_NAME = RedfishPlatformHostInterfaceLibNull + FILE_GUID = 851229BF-4D8B-30F3-DD0D-20AFAF99A77B + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = RedfishPlatformHostInterfaceLib + +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64 +# + +[Sources] + PlatformHostInterfaceLibNull.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + +[LibraryClasses] + UefiLib + BaseLib + diff --git a/CdeEmuPkg/RedfishPkg/Library/RedfishContentCodingLibNull/RedfishContentCodingLibNull.c b/CdeEmuPkg/RedfishPkg/Library/RedfishContentCodingLibNull/RedfishContentCodingLibNull.c new file mode 100644 index 00000000000..0264b365a14 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/RedfishContentCodingLibNull/RedfishContentCodingLibNull.c @@ -0,0 +1,81 @@ +/** @file + NULL instace of RedfishContentCodingLib + + (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include + +/** + This is the function to encode the content use the + algorithm indicated in ContentEncodedValue. The naming of + ContentEncodedValue is follow HTTP spec or could be a + platform-specific value. + + @param[in] ContentEncodedValue HTTP conent encoded value. + The value could be one of below + or any which is platform-specific. + - HTTP_CONTENT_ENCODING_IDENTITY "identity" + - HTTP_CONTENT_ENCODING_GZIP "gzip" + - HTTP_CONTENT_ENCODING_COMPRESS "compress" + - HTTP_CONTENT_ENCODING_DEFLATE "deflate" + - HTTP_CONTENT_ENCODING_BROTLI "br" + @param[in] OriginalContent Original content. + @param[in] OriginalContentLength The length of original content. + @param[out] EncodedContentPointer Pointer to receive the encoded content pointer. + @param[out] EncodedContentLength Length of encoded content. + + @retval EFI_SUCCESS Content is encoded successfully. + @retval EFI_UNSUPPORTED No supported encoding funciton, + @retval EFI_INVALID_PARAMETER One of the given parameter is invalid. + +**/ +EFI_STATUS +RedfishContentEncode ( + IN CHAR8 *ContentEncodedValue, + IN CHAR8 *OriginalContent, + IN UINTN OriginalContentLength, + OUT VOID **EncodedContentPointer, + OUT UINTN *EncodedContentLength + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This is the function to decode the content use the + algorithm indicated in ContentEncodedValue. The naming of + ContentEncodedValue is follow HTTP spec or could be a + platform-specific value. + + @param[in] ContentDecodedValue HTTP conent decoded value. + The value could be one of below + or any which is platform-specific. + - HTTP_CONTENT_ENCODING_IDENTITY "identity" + - HTTP_CONTENT_ENCODING_GZIP "gzip" + - HTTP_CONTENT_ENCODING_COMPRESS "compress" + - HTTP_CONTENT_ENCODING_DEFLATE "deflate" + - HTTP_CONTENT_ENCODING_BROTLI "br" + @param[in] ContentPointer Original content. + @param[in] ContentLength The length of original content. + @param[out] DecodedContentPointer Pointer to receive decoded content pointer. + @param[out] DecodedContentLength Length of decoded content. + + @retval EFI_SUCCESS Content is decoded successfully. + @retval EFI_UNSUPPORTED No supported decoding funciton, + @retval EFI_INVALID_PARAMETER One of the given parameter is invalid. + +**/ +EFI_STATUS +RedfishContentDecode ( + IN CHAR8 *ContentDecodedValue, + IN VOID *ContentPointer, + IN UINTN ContentLength, + OUT VOID **DecodedContentPointer, + OUT UINTN *DecodedContentLength + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/CdeEmuPkg/RedfishPkg/Library/RedfishContentCodingLibNull/RedfishContentCodingLibNull.inf b/CdeEmuPkg/RedfishPkg/Library/RedfishContentCodingLibNull/RedfishContentCodingLibNull.inf new file mode 100644 index 00000000000..2a74d7fab31 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Library/RedfishContentCodingLibNull/RedfishContentCodingLibNull.inf @@ -0,0 +1,31 @@ +## @file +# NULL instance of RedfishContentCodingLibNull +# This library is used to encode/decode Redfish payload. +# +# (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001000b + BASE_NAME = RedfishContentCodingLibNull + FILE_GUID = 06B10249-4D38-FF37-0CA5-13AFB6D625CC + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = RedfishContentCodingLib + +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64 +# + +[Sources] + RedfishContentCodingLibNull.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + + diff --git a/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/assert.h b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/assert.h new file mode 100644 index 00000000000..778f142ed61 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/assert.h @@ -0,0 +1,16 @@ +/** @file + Include file to support building the third-party jansson library. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef REDFISH_CRT_ASSERT_H_ +#define REDFISH_CRT_ASSERT_H_ + +#include + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/errno.h b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/errno.h new file mode 100644 index 00000000000..98a9979d912 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/errno.h @@ -0,0 +1,16 @@ +/** @file + Include file to support building the third-party jansson library. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef REDFISH_CRT_ERRNO_H_ +#define REDFISH_CRT_ERRNO_H_ + +#include + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/limits.h b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/limits.h new file mode 100644 index 00000000000..1b97a3cc505 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/limits.h @@ -0,0 +1,16 @@ +/** @file + Include file to support building the third-party jansson library. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef REDFISH_CRT_LIMITS_H_ +#define REDFISH_CRT_LIMITS_H_ + +#include + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/math.h b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/math.h new file mode 100644 index 00000000000..503f844a82b --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/math.h @@ -0,0 +1,16 @@ +/** @file + Include file to support building the third-party jansson library. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef REDFISH_CRT_MATH_H_ +#define REDFISH_CRT_MATH_H_ + +#include + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/stdarg.h b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/stdarg.h new file mode 100644 index 00000000000..e4ea626b142 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/stdarg.h @@ -0,0 +1,15 @@ +/** @file + Include file to support building the third-party jansson library. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef REDFISH_CRT_STDARG_H_ +#define REDFISH_CRT_STDARG_H_ + +#include + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/stddef.h b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/stddef.h new file mode 100644 index 00000000000..35ed2e975af --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/stddef.h @@ -0,0 +1,16 @@ +/** @file + Include file to support building the third-party jansson library. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef REDFISH_CRT_STDDEF_H_ +#define REDFISH_CRT_STDDEF_H_ + +#include + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/stdio.h b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/stdio.h new file mode 100644 index 00000000000..4ee8889bb52 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/stdio.h @@ -0,0 +1,15 @@ +/** @file + Include file to support building the third-party jansson library. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef REDFISH_CRT_STDIO_H_ +#define REDFISH_CRT_STDIO_H_ + +#include + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/stdlib.h b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/stdlib.h new file mode 100644 index 00000000000..db7a3e64646 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/stdlib.h @@ -0,0 +1,16 @@ +/** @file + Include file to support building the third-party jansson library. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef REDFISH_CRT_STDLIB_H_ +#define REDFISH_CRT_STDLIB_H_ + +#include + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/string.h b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/string.h new file mode 100644 index 00000000000..af23842a69a --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/string.h @@ -0,0 +1,16 @@ +/** @file + Include file to support building the third-party jansson library. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef REDFISH_CRT_STRING_H_ +#define REDFISH_CRT_STRING_H_ + +#include + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/sys/time.h b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/sys/time.h new file mode 100644 index 00000000000..324c6ba72ea --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/sys/time.h @@ -0,0 +1,15 @@ +/** @file + Include file to support building the third-party jansson library. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef REDFISH_CRT_SYS_TIME_H_ +#define REDFISH_CRT_SYS_TIME_H_ + +#include + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/sys/types.h b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/sys/types.h new file mode 100644 index 00000000000..df46193d675 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/sys/types.h @@ -0,0 +1,15 @@ +/** @file + Include file to support building the third-party jansson library. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef REDFISH_CRT_SYS_TYPES_H_ +#define REDFISH_CRT_SYS_TYPES_H_ + +#include + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/time.h b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/time.h new file mode 100644 index 00000000000..1f7a698b26a --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateInclude/Crt/time.h @@ -0,0 +1,15 @@ +/** @file + Include file to support building the third-party jansson library. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef REDFISH_CRT_TIME_H_ +#define REDFISH_CRT_TIME_H_ + +#include + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateInclude/Library/RedfishLib.h b/CdeEmuPkg/RedfishPkg/PrivateInclude/Library/RedfishLib.h new file mode 100644 index 00000000000..c3069f0dd4c --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateInclude/Library/RedfishLib.h @@ -0,0 +1,611 @@ +/** @file + This library provides a set of utility APIs that allow to create/read/update/delete + (CRUD) Redfish resources and provide basic query abilities by using [URI/RedPath] + (https://github.com/DMTF/libredfish). + + The query language is based on XPath (https://www.w3.org/TR/1999/REC-xpath-19991116/). + This library and query language essentially treat the entire Redfish Service like it + was a single JSON document. In other words whenever it encounters an odata.id in JSON + document, it will retrieve the new JSON document (if needed). We name the path as + RedPath: + + Expression Description + + nodename Selects the JSON entity with the name "nodename". + If the value of nodename is an object with "@odata.id", + it will continue get the value from "@odata.id". + + / Selects from the root node + + [index] Selects the index number JSON entity from an array or + object. If the JSON entity is one collection (has + Members & Members@odata.count), means to get the index + member in "Members". Index number >=1, 1 means to return + the first instance. + + [XXX] Operation on JSON entity. + If the JSON entity is one collection (has Members & + Members@odata.count), means to get all elements in + "Members". If the JSON entity is one array, means to + get all elements in array. Others will match the nodename + directly (e.g. JSON_OBJECT, JSON_STRING, JSON_TRUE, + JSON_FALSE, JSON_INTEGER). + + [nodename] Selects all the elements from an JSON entity that + contain a property named "nodename" + + [name=value] Selects all the elements from an JSON entity where + the property "name" is equal to "value" + + [name~value] Selects all the elements from an JSON entity where + the string property "name" is equal to "value" using + case insensitive comparison. + + [namevalue] Selects all the elements from an JSON entity where + the property "name" is greater than "value" + + [name>=value] Selects all the elements from an JSON entity where + the property "name" is greater than or equal to "value" + + Some examples: + + /v1/Chassis[1] - Will return the first Chassis instance. + /v1/Chassis[SKU=1234] - Will return all Chassis instances with a SKU field equal to 1234. + /v1/Systems[Storage] - Will return all the System instances that have Storage field populated. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef REDFISH_LIB_H_ +#define REDFISH_LIB_H_ + +#include + +#include +#include + +#define ODATA_TYPE_NAME_MAX_SIZE 128 +#define ODATA_TYPE_MAX_SIZE 128 + +/// +/// Library class public defines +/// +typedef VOID* REDFISH_SERVICE; +typedef VOID* REDFISH_PAYLOAD; + +/// +/// Library class public structures/unions +/// +typedef struct { + EFI_HTTP_STATUS_CODE *StatusCode; + UINTN HeaderCount; + EFI_HTTP_HEADER *Headers; + REDFISH_PAYLOAD Payload; +} REDFISH_RESPONSE; + +/// +/// Odata type-name mapping structure. +/// +typedef struct { + CONST CHAR8 OdataTypeName [ODATA_TYPE_NAME_MAX_SIZE]; + CONST CHAR8 OdataType [ODATA_TYPE_MAX_SIZE]; +} REDFISH_ODATA_TYPE_MAPPING; + +/** + This function uses REST EX protocol provided in RedfishConfigServiceInfo. + The service enumerator will also handle the authentication flow automatically + if HTTP basic auth or Redfish session login is configured to use. + + Callers are responsible for freeing the returned service by RedfishCleanupService(). + + @param[in] RedfishConfigServiceInfo Redfish service information the EFI Redfish + feature driver communicates with. + + @return New created Redfish Service, or NULL if error happens. + +**/ +REDFISH_SERVICE +EFIAPI +RedfishCreateService ( + IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo + ); + +/** + Free the Service and all its related resources. + + @param[in] RedfishService The Service to access the Redfish resources. + +**/ +VOID +EFIAPI +RedfishCleanupService ( + IN REDFISH_SERVICE RedfishService + ); + +/** + Create REDFISH_PAYLOAD instance in local with JSON represented resource value and + the Redfish Service. + + The returned REDFISH_PAYLOAD can be used to create or update Redfish resource in + server side. + + Callers are responsible for freeing the returned payload by RedfishCleanupPayload(). + + @param[in] Value JSON Value of the redfish resource. + @param[in] RedfishService The Service to access the Redfish resources. + + @return REDFISH_PAYLOAD instance of the resource, or NULL if error happens. + +**/ +REDFISH_PAYLOAD +EFIAPI +RedfishCreatePayload ( + IN EDKII_JSON_VALUE Value, + IN REDFISH_SERVICE RedfishService + ); + +/** + Free the RedfishPayload and all its related resources. + + @param[in] Payload Payload to be freed. + +**/ +VOID +EFIAPI +RedfishCleanupPayload ( + IN REDFISH_PAYLOAD Payload + ); + +/** + This function returns the decoded JSON value of a REDFISH_PAYLOAD. + + Caller doesn't need to free the returned JSON value because it will be released + in corresponding RedfishCleanupPayload() function. + + @param[in] Payload A REDFISH_PAYLOAD instance. + + @return Decoded JSON value of the payload. + +**/ +EDKII_JSON_VALUE +EFIAPI +RedfishJsonInPayload ( + IN REDFISH_PAYLOAD Payload + ); + +/** + Fill the input RedPath string with system UUID from SMBIOS table or use the customized + ID if FromSmbios == FALSE. + + This is a helper function to build a RedPath string which can be used to address + a Redfish resource for this computer system. The input PathString must have a Systems + note in format of "Systems[UUID=%g]" or "Systems[UUID~%g]" to fill the UUID value. + + Example: + Use "/v1/Systems[UUID=%g]/Bios" to build a RedPath to address the "Bios" resource + for this computer system. + + @param[in] RedPath RedPath format to be build. + @param[in] FromSmbios Get system UUID from SMBIOS as computer system instance ID. + @param[in] IdString The computer system instance ID. + + @return Full RedPath with system UUID inside, or NULL if error happens. + +**/ +CHAR8 * +EFIAPI +RedfishBuildPathWithSystemUuid ( + IN CONST CHAR8 *RedPath, + IN BOOLEAN FromSmbios, + IN CHAR8 *IdString OPTIONAL + ); + +/** + Get a redfish response addressed by a RedPath string, including HTTP StatusCode, Headers + and Payload which record any HTTP response messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] RedfishService The Service to access the Redfish resources. + @param[in] RedPath RedPath string to address a resource, must start + from the root node. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not + NULL and the value is 2XX. The corresponding redfish resource has + been returned in Payload within RedResponse. + @retval EFI_INVALID_PARAMETER RedfishService, RedPath, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned Payload is NULL, indicates any error happen. + 2. If the returned StatusCode is NULL, indicates any error happen. + 3. If the returned StatusCode is not 2XX, indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishGetByService ( + IN REDFISH_SERVICE RedfishService, + IN CONST CHAR8 *RedPath, + OUT REDFISH_RESPONSE *RedResponse + ); + +/** + Get a redfish response addressed by URI, including HTTP StatusCode, Headers + and Payload which record any HTTP response messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] RedfishService The Service to access the URI resources. + @param[in] URI String to address a resource. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not + NULL and the value is 2XX. The corresponding redfish resource has + been returned in Payload within RedResponse. + @retval EFI_INVALID_PARAMETER RedfishService, RedPath, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned Payload is NULL, indicates any error happen. + 2. If the returned StatusCode is NULL, indicates any error happen. + 3. If the returned StatusCode is not 2XX, indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishGetByUri ( + IN REDFISH_SERVICE RedfishService, + IN CONST CHAR8 *Uri, + OUT REDFISH_RESPONSE *RedResponse + ); + +/** + Get a redfish response addressed by the input Payload and relative RedPath string, + including HTTP StatusCode, Headers and Payload which record any HTTP response messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] Payload A existing REDFISH_PAYLOAD instance. + @param[in] RedPath Relative RedPath string to address a resource inside Payload. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful: + 1. The HTTP StatusCode is NULL and the returned Payload in + RedResponse is not NULL, indicates the Redfish resource has + been parsed from the input payload directly. + 2. The HTTP StatusCode is not NULL and the value is 2XX, + indicates the corresponding redfish resource has been returned + in Payload within RedResponse. + @retval EFI_INVALID_PARAMETER Payload, RedPath, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned Payload is NULL, indicates any error happen. + 2. If StatusCode is not NULL and the returned value of StatusCode + is not 2XX, indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishGetByPayload ( + IN REDFISH_PAYLOAD Payload, + IN CONST CHAR8 *RedPath, + OUT REDFISH_RESPONSE *RedResponse + ); + +/** + Use HTTP PATCH to perform updates on pre-existing Redfish resource. + + This function uses the RedfishService to patch a Redfish resource addressed by + Uri (only the relative path is required). Changes to one or more properties within + the target resource are represented in the input Content, properties not specified + in Content won't be changed by this request. The corresponding redfish response will + returned, including HTTP StatusCode, Headers and Payload which record any HTTP response + messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] RedfishService The Service to access the Redfish resources. + @param[in] Uri Relative path to address the resource. + @param[in] Content JSON represented properties to be update. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not + NULL and the value is 2XX. The Redfish resource will be returned + in Payload within RedResponse if server send it back in the HTTP + response message body. + @retval EFI_INVALID_PARAMETER RedfishService, Uri, Content, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned StatusCode is NULL, indicates any error happen. + 2. If the returned StatusCode is not NULL and the value is not 2XX, + indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishPatchToUri ( + IN REDFISH_SERVICE RedfishService, + IN CONST CHAR8 *Uri, + IN CONST CHAR8 *Content, + OUT REDFISH_RESPONSE *RedResponse + ); + +/** + Use HTTP PATCH to perform updates on target payload. Patch to odata.id in Payload directly. + + This function uses the Payload to patch the Target. Changes to one or more properties + within the target resource are represented in the input Payload, properties not specified + in Payload won't be changed by this request. The corresponding redfish response will + returned, including HTTP StatusCode, Headers and Payload which record any HTTP response + messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] Target The target payload to be updated. + @param[in] Payload Palyoad with properties to be changed. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not + NULL and the value is 2XX. The Redfish resource will be returned + in Payload within RedResponse if server send it back in the HTTP + response message body. + @retval EFI_INVALID_PARAMETER Target, Payload, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned StatusCode is NULL, indicates any error happen. + 2. If the returned StatusCode is not NULL and the value is not 2XX, + indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishPatchToPayload ( + IN REDFISH_PAYLOAD Target, + IN REDFISH_PAYLOAD Payload, + OUT REDFISH_RESPONSE *RedResponse + ); + +/** + Use HTTP POST to create a new resource in target payload. + + The POST request should be submitted to the Resource Collection in which the new resource + is to belong. The Resource Collection is addressed by Target payload. The Redfish may + ignore any service controlled properties. The corresponding redfish response will returned, + including HTTP StatusCode, Headers and Payload which record any HTTP response messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] Target Target payload of the Resource Collection. + @param[in] Payload The new resource to be created. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not + NULL and the value is 2XX. The Redfish resource will be returned + in Payload within RedResponse if server send it back in the HTTP + response message body. + @retval EFI_INVALID_PARAMETER Target, Payload, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned StatusCode is NULL, indicates any error happen. + 2. If the returned StatusCode is not NULL and the value is not 2XX, + indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishPostToPayload ( + IN REDFISH_PAYLOAD Target, + IN REDFISH_PAYLOAD Payload, + OUT REDFISH_RESPONSE *RedResponse + ); + +/** + Use HTTP DELETE to remove a resource. + + This function uses the RedfishService to remove a Redfish resource which is addressed + by input Uri (only the relative path is required). The corresponding redfish response will + returned, including HTTP StatusCode, Headers and Payload which record any HTTP response + messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] RedfishService The Service to access the Redfish resources. + @param[in] Uri Relative path to address the resource. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not + NULL and the value is 2XX, the Redfish resource has been removed. + If there is any message returned from server, it will be returned + in Payload within RedResponse. + @retval EFI_INVALID_PARAMETER RedfishService, Uri, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned StatusCode is NULL, indicates any error happen. + 2. If the returned StatusCode is not NULL and the value is not 2XX, + indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishDeleteByUri ( + IN REDFISH_SERVICE RedfishService, + IN CONST CHAR8 *Uri, + OUT REDFISH_RESPONSE *RedResponse + ); + +/** + Dump text in fractions. + + @param[in] String ASCII string to dump. + +**/ +VOID +RedfishDumpJsonStringFractions ( + IN CHAR8 *String + ); + +/** + Extract the JSON text content from REDFISH_PAYLOAD and dump to debug console. + + @param[in] Payload The Redfish payload to dump. + +**/ +VOID +RedfishDumpPayload ( + IN REDFISH_PAYLOAD Payload + ); +/** + Dump text in JSON value. + + @param[in] JsonValue The Redfish JSON value to dump. + +**/ +VOID +RedfishDumpJson ( + IN EDKII_JSON_VALUE JsonValue + ); +/** + This function will cleanup the HTTP header and Redfish payload resources. + + @param[in] StatusCode The status code in HTTP response message. + @param[in] HeaderCount Number of HTTP header structures in Headers list. + @param[in] Headers Array containing list of HTTP headers. + @param[in] Payload The Redfish payload to dump. + +**/ +VOID +RedfishFreeResponse ( + IN EFI_HTTP_STATUS_CODE *StatusCode, + IN UINTN HeaderCount, + IN EFI_HTTP_HEADER *Headers, + IN REDFISH_PAYLOAD Payload + ); + +/** + Check if the "@odata.type" in Payload is valid or not. + + @param[in] Payload The Redfish payload to be checked. + @param[in] OdataTypeName OdataType will be retrived from mapping list. + @param[in] OdataTypeMappingList The list of OdataType. + @param[in] OdataTypeMappingListSize The number of mapping list + + @return TRUE if the "@odata.type" in Payload is valid, otherwise FALSE. + +**/ +BOOLEAN +RedfishIsValidOdataType ( + IN REDFISH_PAYLOAD Payload, + IN CONST CHAR8 *OdataTypeName, + IN REDFISH_ODATA_TYPE_MAPPING *OdataTypeMappingList, + IN UINTN OdataTypeMappingListSize + ); + +/** + Check if the payload is collection + + @param[in] Payload The Redfish payload to be checked. + + @return TRUE if the payload is collection. + +**/ +BOOLEAN +RedfishIsPayloadCollection ( + IN REDFISH_PAYLOAD Payload +); +/** + Get collection size. + + @param[in] Payload The Redfish collection payload + @param[in] CollectionSize Size of this collection + + @return EFI_SUCCESS Coolection size is returned in CollectionSize + @return EFI_INVALID_PARAMETER The payload is not a collection. +**/ +EFI_STATUS +RedfishGetCollectionSize( + IN REDFISH_PAYLOAD Payload, + IN UINTN *CollectionSize +); +/** + Get Redfish payload of collection member + + @param[in] Payload The Redfish collection payload + @param[in] Index Index of collection member + + @return NULL Fail to get collection member. + @return Non NULL Payload is returned. +**/ +REDFISH_PAYLOAD +RedfishGetPayloadByIndex ( + IN REDFISH_PAYLOAD Payload, + IN UINTN Index +); + +/** + Check and return Redfish resource of the given Redpath. + + @param[in] RedfishService Pointer to REDFISH_SERVICE + @param[in] Redpath Redpath of the resource. + @param[in] Response Optional return the resource. + + @return EFI_STATUS +**/ +EFI_STATUS +RedfishCheckIfRedpathExist ( + IN REDFISH_SERVICE RedfishService, + IN CHAR8 *Redpath, + IN REDFISH_RESPONSE *Response OPTIONAL +); + +/** + This function returns the string of Redfish service version. + + @param[in] RedfishService Redfish service instance. + @param[out] ServiceVersionStr Redfish service string. + + @return EFI_STATUS + +**/ +EFI_STATUS +RedfishGetServiceVersion( + IN REDFISH_SERVICE RedfishService, + OUT CHAR8 **ServiceVersionStr + ); + +/** + This function returns the string of Redfish service version. + + @param[in] ServiceVerisonStr The string of Redfish service version. + @param[in] Url The URL to build Redpath with ID. + Start with "/", for example "/Registries" + @param[in] Id ID string + @param[out] Redpath Pointer to retrive Redpath, caller has to free + the memory allocated for this string. + @return EFI_STATUS + +**/ +EFI_STATUS +RedfishBuildRedpathUseId ( + IN CHAR8 *ServiceVerisonStr, + IN CHAR8 *Url, + IN CHAR8 *Id, + OUT CHAR8 **Redpath + ); +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishCrtLib/RedfishCrtLib.c b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishCrtLib/RedfishCrtLib.c new file mode 100644 index 00000000000..401c8084b8b --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishCrtLib/RedfishCrtLib.c @@ -0,0 +1,929 @@ +/** @file + CRT wrapper functions for system call,the string operation functions + are remodeled after edk2-libc. + + 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 + +int errno = 0; +char errnum_message [] = "We don't support to map errnum to the error message on edk2 Redfish\n"; + +// This is required to keep VC++ happy if you use floating-point +int _fltused = 1; + +/** + Determine if a particular character is an alphanumeric character + @return Returns 1 if c is an alphanumeric character, otherwise returns 0. +**/ +int isalnum (int c) +{ + // + // ::= [0-9] | [a-z] | [A-Z] + // + return ((('0' <= (c)) && ((c) <= '9')) || + (('a' <= (c)) && ((c) <= 'z')) || + (('A' <= (c)) && ((c) <= 'Z'))); +} + +/** + Determine if a particular character is a digital character + + @return Returns 1 if c is an digital character, otherwise returns 0. +**/ +int isdchar (int c) +{ + // + // [0-9] | [e +-.] + // + return ((('0' <= (c)) && ((c) <= '9')) || + (c == 'e') || (c == 'E') || + (c == '+') || (c == '-') || + (c == '.')); +} + +/** + Determine if a particular character is a space character + + @return Returns 1 if c is a space character +**/ +int isspace (int c) +{ + // + // ::= [ ] + // + return ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n') || ((c) == '\v') || ((c) == '\f'); +} + +/** + Allocates memory blocks +*/ +void *malloc (size_t size) +{ + return AllocatePool ((UINTN) size); +} + +/** + De-allocates or frees a memory block +*/ +void free (void *ptr) +{ + // + // In Standard C, free() handles a null pointer argument transparently. This + // is not true of FreePool() below, so protect it. + // + if (ptr != NULL) { + FreePool (ptr); + } +} + +/** + NetBSD Compatibility Function strdup creates a duplicate copy of a string. + + @return Returns the pointer to duplicated string. +**/ +char * strdup(const char *str) +{ + size_t len; + char *copy; + + len = strlen(str) + 1; + if ((copy = malloc(len)) == NULL) + return (NULL); + memcpy(copy, str, len); + return (copy); +} + +/** The toupper function converts a lowercase letter to a corresponding + uppercase letter. + + @param[in] c The character to be converted. + + @return If the argument is a character for which islower is true and + there are one or more corresponding characters, as specified by + the current locale, for which isupper is true, the toupper + function returns one of the corresponding characters (always the + same one for any given locale); otherwise, the argument is + returned unchanged. +**/ +int +toupper( + IN int c + ) +{ + if ( (c >= 'a') && (c <= 'z') ) { + c = c - ('a' - 'A'); + } + return c; +} + +/** + Digit to a value. + + @return Returns the value of digit. +**/ +int +Digit2Val( int c) +{ + if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) { /* If c is one of [A-Za-z]... */ + c = toupper(c) - 7; // Adjust so 'A' is ('9' + 1) + } + return c - '0'; // Value returned is between 0 and 35, inclusive. +} + + +/** The strtoll function converts the initial portion of the string pointed to + by nptr to long long int representation. + + See the description for strtol for more information. + + @return The strtoll function returns the converted value, if any. If no + conversion could be performed, zero is returned. If the correct + value is outside the range of representable values, LLONG_MIN or + LLONG_MAX is returned (according to the sign of the value, if any), + and the value of the macro ERANGE is stored in errno. +**/ +long long +strtoll(const char * nptr, char ** endptr, int base) +{ + const char *pEnd; + long long Result = 0; + long long Previous; + int temp; + BOOLEAN Negative = FALSE; + + pEnd = nptr; + + if((base < 0) || (base == 1) || (base > 36)) { + if(endptr != NULL) { + *endptr = NULL; + } + return 0; + } + // Skip leading spaces. + while(isspace(*nptr)) ++nptr; + + // Process Subject sequence: optional sign followed by digits. + if(*nptr == '+') { + Negative = FALSE; + ++nptr; + } + else if(*nptr == '-') { + Negative = TRUE; + ++nptr; + } + + if(*nptr == '0') { /* Might be Octal or Hex */ + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */ + if((base == 0) || (base == 16)) { + nptr += 2; /* Skip the "0X" */ + base = 16; /* In case base was 0 */ + } + } + else { /* Looks like Octal */ + if((base == 0) || (base == 8)) { + ++nptr; /* Skip the leading "0" */ + base = 8; /* In case base was 0 */ + } + } + } + if(base == 0) { /* If still zero then must be decimal */ + base = 10; + } + if(*nptr == '0') { + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */ + pEnd = nptr; + } + + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) { + Previous = Result; + Result = MultS64x64 (Result, base) + (long long int)temp; + if( Result <= Previous) { // Detect Overflow + if(Negative) { + Result = LLONG_MIN; + } + else { + Result = LLONG_MAX; + } + Negative = FALSE; + errno = ERANGE; + break; + } + pEnd = ++nptr; + } + if(Negative) { + Result = -Result; + } + + // Save pointer to final sequence + if(endptr != NULL) { + *endptr = (char *)pEnd; + } + return Result; +} + +/** The strtol, strtoll, strtoul, and strtoull functions convert the initial + portion of the string pointed to by nptr to long int, long long int, + unsigned long int, and unsigned long long int representation, respectively. + First, they decompose the input string into three parts: an initial, + possibly empty, sequence of white-space characters (as specified by the + isspace function), a subject sequence resembling an integer represented in + some radix determined by the value of base, and a final string of one or + more unrecognized characters, including the terminating null character of + the input string. Then, they attempt to convert the subject sequence to an + integer, and return the result. + + If the value of base is zero, the expected form of the subject sequence is + that of an integer constant, optionally preceded + by a plus or minus sign, but not including an integer suffix. If the value + of base is between 2 and 36 (inclusive), the expected form of the subject + sequence is a sequence of letters and digits representing an integer with + the radix specified by base, optionally preceded by a plus or minus sign, + but not including an integer suffix. The letters from a (or A) through z + (or Z) are ascribed the values 10 through 35; only letters and digits whose + ascribed values are less than that of base are permitted. If the value of + base is 16, the characters 0x or 0X may optionally precede the sequence of + letters and digits, following the sign if present. + + The subject sequence is defined as the longest initial subsequence of the + input string, starting with the first non-white-space character, that is of + the expected form. The subject sequence contains no characters if the input + string is empty or consists entirely of white space, or if the first + non-white-space character is other than a sign or a permissible letter or digit. + + If the subject sequence has the expected form and the value of base is + zero, the sequence of characters starting with the first digit is + interpreted as an integer constant. If the subject sequence has the + expected form and the value of base is between 2 and 36, it is used as the + base for conversion, ascribing to each letter its value as given above. If + the subject sequence begins with a minus sign, the value resulting from the + conversion is negated (in the return type). A pointer to the final string + is stored in the object pointed to by endptr, provided that endptr is + not a null pointer. + + In other than the "C" locale, additional locale-specific subject sequence + forms may be accepted. + + If the subject sequence is empty or does not have the expected form, no + conversion is performed; the value of nptr is stored in the object pointed + to by endptr, provided that endptr is not a null pointer. + + @return The strtol, strtoll, strtoul, and strtoull functions return the + converted value, if any. If no conversion could be performed, zero + is returned. If the correct value is outside the range of + representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, + ULONG_MAX, or ULLONG_MAX is returned (according to the return type + and sign of the value, if any), and the value of the macro ERANGE + is stored in errno. +**/ +long +strtol(const char * nptr, char ** endptr, int base) +{ + const char *pEnd; + long Result = 0; + long Previous; + int temp; + BOOLEAN Negative = FALSE; + + pEnd = nptr; + + if((base < 0) || (base == 1) || (base > 36)) { + if(endptr != NULL) { + *endptr = NULL; + } + return 0; + } + // Skip leading spaces. + while(isspace(*nptr)) ++nptr; + + // Process Subject sequence: optional sign followed by digits. + if(*nptr == '+') { + Negative = FALSE; + ++nptr; + } + else if(*nptr == '-') { + Negative = TRUE; + ++nptr; + } + + if(*nptr == '0') { /* Might be Octal or Hex */ + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */ + if((base == 0) || (base == 16)) { + nptr += 2; /* Skip the "0X" */ + base = 16; /* In case base was 0 */ + } + } + else { /* Looks like Octal */ + if((base == 0) || (base == 8)) { + ++nptr; /* Skip the leading "0" */ + base = 8; /* In case base was 0 */ + } + } + } + if(base == 0) { /* If still zero then must be decimal */ + base = 10; + } + if(*nptr == '0') { + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */ + pEnd = nptr; + } + + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) { + Previous = Result; + Result = (Result * base) + (long int)temp; + if( Result <= Previous) { // Detect Overflow + if(Negative) { + Result = LONG_MIN; + } + else { + Result = LONG_MAX; + } + Negative = FALSE; + errno = ERANGE; + break; + } + pEnd = ++nptr; + } + if(Negative) { + Result = -Result; + } + + // Save pointer to final sequence + if(endptr != NULL) { + *endptr = (char *)pEnd; + } + return Result; +} + +/** The strtoull function converts the initial portion of the string pointed to + by nptr to unsigned long long int representation. + + See the description for strtol for more information. + + @return The strtoull function returns the converted value, if any. If no + conversion could be performed, zero is returned. If the correct + value is outside the range of representable values, ULLONG_MAX is + returned and the value of the macro ERANGE is stored in errno. +**/ +unsigned long long +strtoull(const char * nptr, char ** endptr, int base) +{ + const char *pEnd; + unsigned long long Result = 0; + unsigned long long Previous; + int temp; + + pEnd = nptr; + + if((base < 0) || (base == 1) || (base > 36)) { + if(endptr != NULL) { + *endptr = NULL; + } + return 0; + } + // Skip leading spaces. + while(isspace(*nptr)) ++nptr; + + // Process Subject sequence: optional + sign followed by digits. + if(*nptr == '+') { + ++nptr; + } + + if(*nptr == '0') { /* Might be Octal or Hex */ + if(toupper(nptr[1]) == 'X') { /* Looks like Hex */ + if((base == 0) || (base == 16)) { + nptr += 2; /* Skip the "0X" */ + base = 16; /* In case base was 0 */ + } + } + else { /* Looks like Octal */ + if((base == 0) || (base == 8)) { + ++nptr; /* Skip the leading "0" */ + base = 8; /* In case base was 0 */ + } + } + } + if(base == 0) { /* If still zero then must be decimal */ + base = 10; + } + if(*nptr == '0') { + for( ; *nptr == '0'; ++nptr); /* Skip any remaining leading zeros */ + pEnd = nptr; + } + + while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) { + Previous = Result; + Result = DivU64x32 (Result, base) + (unsigned long long)temp; + if( Result < Previous) { // If we overflowed + Result = ULLONG_MAX; + errno = ERANGE; + break; + } + pEnd = ++nptr; + } + + // Save pointer to final sequence + if(endptr != NULL) { + *endptr = (char *)pEnd; + } + return Result; +} + +/** + edk2 Jansson port does not support doubles, simply return 0. + + These conversion functions convert the initial portion of the string + pointed to by nptr to double, float, and long double representation, + respectively. + + The strtod(), strtof(), and strtold() functions return the converted + value, if any. + + If endptr is not NULL, a pointer to the character after the last charac- + ter used in the conversion is stored in the location referenced by + endptr. + + If no conversion is performed, zero is returned and the value of nptr is + stored in the location referenced by endptr. + + If the correct value would cause overflow, plus or minus HUGE_VAL, + HUGE_VALF, or HUGE_VALL is returned (according to the sign and type of + the return value), and ERANGE is stored in errno. If the correct value + would cause underflow, zero is returned and ERANGE is stored in errno. + + @return Return 0. +**/ +double +strtod (const char * __restrict nptr, char ** __restrict endptr) { + + DEBUG((DEBUG_INFO, "We don't supprot double type on edk2 yet!")); + ASSERT(FALSE); + return (double)0; +} + +static UINT8 BitMask[] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 + }; + +#define WHICH8(c) ((unsigned char)(c) >> 3) +#define WHICH_BIT(c) (BitMask[((c) & 0x7)]) +#define BITMAP64 ((UINT64 *)bitmap) + +static +void +BuildBitmap(unsigned char * bitmap, const char *s2, int n) +{ + unsigned char bit; + int index; + + // Initialize bitmap. Bit 0 is always 1 which corresponds to '\0' + for (BITMAP64[0] = index = 1; index < n; index++) { + BITMAP64[index] = 0; + } + + // Set bits in bitmap corresponding to the characters in s2 + for (; *s2 != '\0'; s2++) { + index = WHICH8(*s2); + bit = WHICH_BIT(*s2); + bitmap[index] = bitmap[index] | bit; + } +} + +/** The strpbrk function locates the first occurrence in the string pointed to + by s1 of any character from the string pointed to by s2. + + @return The strpbrk function returns a pointer to the character, or a + null pointer if no character from s2 occurs in s1. +**/ +char * +strpbrk(const char *s1, const char *s2) +{ + UINT8 bitmap[ (((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U]; + UINT8 bit; + int index; + + BuildBitmap( bitmap, s2, sizeof(bitmap) / sizeof(UINT64)); + + for( ; *s1 != '\0'; ++s1) { + index = WHICH8(*s1); + bit = WHICH_BIT(*s1); + if( (bitmap[index] & bit) != 0) { + return (char *)s1; + } + } + return NULL; +} + +/** The strerror function maps the number in errnum to a message string. + Typically, the values for errnum come from errno, but strerror shall map + any value of type int to a message. + + The implementation shall behave as if no library function calls the + strerror function. + + @return The strerror function returns a pointer to the string, the + contents of which are locale specific. The array pointed to + shall not be modified by the program, but may be overwritten by + a subsequent call to the strerror function. +**/ +char * +strerror(int errnum) +{ + return errnum_message; +} + +/** + Allocate and zero-initialize array. +**/ +void * +calloc(size_t Num, size_t Size) +{ + void *RetVal; + size_t NumSize; + + NumSize = Num * Size; + RetVal = NULL; + if (NumSize != 0) { + RetVal = malloc(NumSize); + if( RetVal != NULL) { + (VOID)ZeroMem( RetVal, NumSize); + } + } + DEBUG((DEBUG_POOL, "0x%p = calloc(%d, %d)\n", RetVal, Num, Size)); + + return RetVal; +} + +// +// The arrays give the cumulative number of days up to the first of the +// month number used as the index (1 -> 12) for regular and leap years. +// The value at index 13 is for the whole year. +// +UINTN CumulativeDays[2][14] = { + { + 0, + 0, + 31, + 31 + 28, + 31 + 28 + 31, + 31 + 28 + 31 + 30, + 31 + 28 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + }, + { + 0, + 0, + 31, + 31 + 29, + 31 + 29 + 31, + 31 + 29 + 31 + 30, + 31 + 29 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30, + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31 + } +}; + +#define IsLeap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) +#define SECSPERMIN (60) +#define SECSPERHOUR (60 * 60) +#define SECSPERDAY (24 * SECSPERHOUR) + +/** + Get the system time as seconds elapsed since midnight, January 1, 1970. +**/ +time_t time (time_t *timer) +{ + EFI_TIME Time; + time_t CalTime; + UINTN Year; + + // + // Get the current time and date information + // + gRT->GetTime (&Time, NULL); + + // + // Years Handling + // UTime should now be set to 00:00:00 on Jan 1 of the current year. + // + for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) { + CalTime = CalTime + (time_t)(CumulativeDays[IsLeap(Year)][13] * SECSPERDAY); + } + + // + // Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment + // + CalTime = CalTime + + (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ? (Time.TimeZone * 60) : 0) + + (time_t)(CumulativeDays[IsLeap(Time.Year)][Time.Month] * SECSPERDAY) + + (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) + + (time_t)(Time.Hour * SECSPERHOUR) + + (time_t)(Time.Minute * 60) + + (time_t)Time.Second; + + if (timer != NULL) { + *timer = CalTime; + } + + return CalTime; +} + +/** + Performs a quick sort +**/ +void qsort (void *base, size_t num, size_t width, int (*compare)(const void *, const void *)) +{ + + ASSERT (base != NULL); + ASSERT (compare != NULL); + + PerformQuickSort (base, (UINTN)num, (UINTN)width, (SORT_COMPARE)compare); + return; +} + +/** + Get character from stream, we don't support file operastion on edk2 JSON library. + + @return Returns the character currently pointed by the internal file position indicator of the specified stream + +**/ +int fgetc(FILE * _File){ + return EOF; +} +/** + Open stream file, we don't support file operastion on edk2 JSON library. + + @return 0 Unsupported + +**/ +FILE *fopen (const char *filename, const char *mode) { + return NULL; +} +/** + Read stream from file, we don't support file operastion on edk2 JSON library. + + @return 0 Unsupported + +**/ +size_t fread (void * ptr, size_t size, size_t count, FILE * stream) { + return 0; +} +/** + Write stream from file, we don't support file operastion on edk2 JSON library. + + @return 0 Unsupported + +**/ +size_t fwrite (const void * ptr, size_t size, size_t count, FILE * stream) { + return 0; +} +/** + Close file, we don't support file operastion on edk2 JSON library. + + @return 0 Unsupported + +**/ +int fclose (FILE * stream) { + return EOF; +} +/** + Write the formatted string to file, we don't support file operastion on edk2 JSON library. + + @return 0 Unsupported + +**/ +int fprintf (FILE * stream, const char * format, ...) { + return -1; +} +/** + This function check if this is the formating string specifier. + + @param[in] FormatString A Null-terminated ASCII format string. + @param[in,out] CurrentPosition The starting position at the given string to check for + "[flags][width][.precision][length]s" string specifier. + @param[in] StrLength Maximum string length. + + @return BOOLEAN TRUE means this is the formating string specifier. CurrentPosition is + returned at the position of "s". + FALSE means this is not the formating string specifier.. CurrentPosition is + returned at the position of failed character. + +**/ +BOOLEAN +CheckFormatingString ( + IN CONST CHAR8 *FormatString, + IN OUT UINTN *CurrentPosition, + IN UINTN StrLength + ) +{ + CHAR8 FormatStringParamater; + + while (*(FormatString + *CurrentPosition) != 's') { + // + // Loop until reach character 's' if the formating string is + // compliant with "[flags][width][.precision][length]" format for + // the string specifier. + // + FormatStringParamater = *(FormatString + *CurrentPosition); + if ((FormatStringParamater != '-') && + (FormatStringParamater != '+') && + (FormatStringParamater != '*') && + (FormatStringParamater != '.') && + !(((UINTN)FormatStringParamater >= (UINTN)'0') && ((UINTN)FormatStringParamater <= (UINTN)'9')) + ) { + return FALSE; + } + (*CurrentPosition)++; + if (*CurrentPosition >= StrLength) { + return FALSE; + } + }; + return TRUE; +} + +/** + This function clones *FormatString however replaces "%s" with "%a" in the + returned string. + + @param[in] A Null-terminated ASCII format string. + + @return The new format string. Caller has to free the memory of this string + using FreePool(). + +**/ +CHAR8 * +ReplaceUnicodeToAsciiStrFormat ( + IN CONST CHAR8 *FormatString +) +{ + UINTN FormatStrSize; + UINTN FormatStrIndex; + UINTN FormatStrSpecifier; + BOOLEAN PercentageMark; + CHAR8 *TempFormatBuffer; + BOOLEAN IsFormatString; + + // + // Error checking. + // + if (FormatString == NULL) { + return NULL; + } + FormatStrSize = AsciiStrSize(FormatString); + if (FormatStrSize == 0) { + return NULL; + } + TempFormatBuffer = AllocatePool(FormatStrSize); // Allocate memory for the + // new string. + if (TempFormatBuffer== NULL) { + return NULL; + } + // + // Clone *FormatString but replace "%s" wih "%a". + // "%%" is not considered as the format tag. + // + PercentageMark = FALSE; + FormatStrIndex = 0; + while (FormatStrIndex < FormatStrSize) { + if (PercentageMark == TRUE) { + // + // Previous character is "%". + // + PercentageMark = FALSE; + if (*(FormatString + FormatStrIndex) != '%') { // Check if this is double "%". + FormatStrSpecifier = FormatStrIndex; + // + // Check if this is the formating string specifier. + // + IsFormatString = CheckFormatingString (FormatString, &FormatStrSpecifier, FormatStrSize); + if ((FormatStrSpecifier - FormatStrIndex) != 0) { + CopyMem((VOID *)(TempFormatBuffer + FormatStrIndex), + (VOID *)(FormatString + FormatStrIndex), + FormatStrSpecifier - FormatStrIndex + ); + } + FormatStrIndex = FormatStrSpecifier; + if (IsFormatString == TRUE) { + // + // Replace 's' with 'a' which is printed in ASCII + // format on edk2 environment. + // + *(TempFormatBuffer + FormatStrSpecifier) = 'a'; + FormatStrIndex ++; + } + continue; + } + goto ContinueCheck; + } + if (*(FormatString + FormatStrIndex) == '%') { + // + // This character is "%", set the flag. + // + PercentageMark = TRUE; + } +ContinueCheck: + // + // Clone character to the new string and advance FormatStrIndex + // to process next character. + // + *(TempFormatBuffer + FormatStrIndex) = *(FormatString + FormatStrIndex); + FormatStrIndex++; + }; + return TempFormatBuffer; +} + +/** + This is the Redfish version of CRT vsnprintf function, this function replaces "%s" to + "%a" before invoking AsciiVSPrint(). That is because "%s" is unicode base on edk2 + environment however "%s" is ascii code base on vsnprintf(). + See definitions of AsciiVSPrint() for the details. + + @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated + ASCII string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString A Null-terminated ASCII format string. + @param Marker VA_LIST marker for the variable argument list. + + @return The number of ASCII characters in the produced output buffer not including the + Null-terminator. + +**/ +UINTN +EFIAPI +RedfishAsciiVSPrint ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + IN VA_LIST Marker + ) +{ + CHAR8 *TempFormatBuffer; + UINTN LenStrProduced; + + // + // Looking for "%s" in the format string and replace it + // with "%a" for printing ASCII code characters on edk2 + // environment. + // + TempFormatBuffer = ReplaceUnicodeToAsciiStrFormat (FormatString); + if (TempFormatBuffer == NULL) { + return 0; + } + LenStrProduced = AsciiVSPrint (StartOfBuffer, BufferSize, (CONST CHAR8 *)TempFormatBuffer, Marker); + FreePool (TempFormatBuffer); + return LenStrProduced; +} + +/** + This is the Redfish version of CRT snprintf function, this function replaces "%s" to + "%a" before invoking AsciiSPrint(). That is because "%s" is unicode base on edk2 + environment however "%s" is ascii code base on snprintf(). + See definitions of AsciiSPrint() for the details. + + @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated + ASCII string. + @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer. + @param FormatString A Null-terminated ASCII format string. + @param ... Variable argument list whose contents are accessed based on the + format string specified by FormatString. + + @return The number of ASCII characters in the produced output buffer not including the + Null-terminator. + +**/ +UINTN +EFIAPI +RedfishAsciiSPrint ( + OUT CHAR8 *StartOfBuffer, + IN UINTN BufferSize, + IN CONST CHAR8 *FormatString, + ... + ) +{ + VA_LIST Marker; + UINTN LenStrProduced; + + VA_START(Marker, FormatString); + LenStrProduced = RedfishAsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker); + return LenStrProduced; +} + diff --git a/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishCrtLib/RedfishCrtLib.inf b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishCrtLib/RedfishCrtLib.inf new file mode 100644 index 00000000000..4dc6be764b0 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishCrtLib/RedfishCrtLib.inf @@ -0,0 +1,38 @@ +## @file +# Redfish C Runtime Library for opensource projects. +# +# 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 = 0x0001001b + BASE_NAME = RedfishCrtLib + FILE_GUID = 8263B8AC-D021-425D-B337-3EC96F5DC19B + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = RedfishCrtLib|DXE_DRIVER UEFI_APPLICATION UEFI_DRIVER + +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64 +# + +[Sources] + RedfishCrtLib.c + +[LibraryClasses] + BaseLib + BaseSortLib + DebugLib + MemoryAllocationLib + UefiRuntimeServicesTableLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + + diff --git a/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/RedfishLib.c b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/RedfishLib.c new file mode 100644 index 00000000000..427e501c4e6 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/RedfishLib.c @@ -0,0 +1,994 @@ +#error +/** @file + Provides a set of utility APIs that allow to create/read/update/delete + (CRUD) Redfish resources and provide basic query. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "RedfishMisc.h" + +/** + This function uses REST EX protocol provided in RedfishConfigServiceInfo. + The service enumerator will also handle the authentication flow automatically + if HTTP basic auth or Redfish session login is configured to use. + + Callers are responsible for freeing the returned service by RedfishCleanupService(). + + @param[in] RedfishConfigServiceInfo Redfish service information the EFI Redfish + feature driver communicates with. + + @return New created Redfish Service, or NULL if error happens. + +**/ +REDFISH_SERVICE +EFIAPI +RedfishCreateService ( + IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo + ) +{ + REDFISH_SERVICE RedfishService; + EDKII_REDFISH_AUTH_METHOD AuthMethod; + CHAR8 *UserId; + CHAR8 *Password; + EFI_STATUS Status; + + RedfishService = NULL; + UserId = NULL; + Password = NULL; + + // + // Check Input Parameters. + // + if (RedfishConfigServiceInfo == NULL) { + return NULL; + } + + // + // Get Authentication Configuration. + // + Status = RedfishGetAuthInfo (&AuthMethod, &UserId, &Password); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + // + // Create a redfish service node based on Redfish network host interface. + // + RedfishService = RedfishCreateLibredfishService ( + RedfishConfigServiceInfo, + AuthMethod, + UserId, + Password + ); + +ON_EXIT: + if (UserId != NULL) { + FreePool (UserId); + } + if (Password!= NULL) { + FreePool (Password); + } + + return RedfishService; +} + +/** + Free the Service and all its related resources. + + @param[in] RedfishService The Service to access the Redfish resources. + +**/ +VOID +EFIAPI +RedfishCleanupService ( + IN REDFISH_SERVICE RedfishService + ) +{ + if (RedfishService == NULL) { + return; + } + + cleanupServiceEnumerator (RedfishService); +} +/** + Create REDFISH_PAYLOAD instance in local with JSON represented resource value and + the Redfish Service. + + The returned REDFISH_PAYLOAD can be used to create or update Redfish resource in + server side. + + Callers are responsible for freeing the returned payload by RedfishCleanupPayload(). + + @param[in] Value JSON Value of the redfish resource. + @param[in] RedfishService The Service to access the Redfish resources. + + @return REDFISH_PAYLOAD instance of the resource, or NULL if error happens. + +**/ +REDFISH_PAYLOAD +EFIAPI +RedfishCreatePayload ( + IN EDKII_JSON_VALUE Value, + IN REDFISH_SERVICE RedfishService + ) +{ + EDKII_JSON_VALUE CopyValue; + + CopyValue = JsonValueClone (Value); + return createRedfishPayload (CopyValue, RedfishService); +} + +/** + Free the RedfishPayload and all its related resources. + + @param[in] Payload Payload to be freed. + +**/ +VOID +EFIAPI +RedfishCleanupPayload ( + IN REDFISH_PAYLOAD Payload + ) +{ + if (Payload == NULL) { + return; + } + + cleanupPayload ((redfishPayload *) Payload); +} + +/** + This function returns the decoded JSON value of a REDFISH_PAYLOAD. + + Caller doesn't need to free the returned JSON value because it will be released + in corresponding RedfishCleanupPayload() function. + + @param[in] Payload A REDFISH_PAYLOAD instance. + + @return Decoded JSON value of the payload. + +**/ +EDKII_JSON_VALUE +EFIAPI +RedfishJsonInPayload ( + IN REDFISH_PAYLOAD Payload + ) +{ + if (Payload == NULL) { + return NULL; + } + + return ((redfishPayload*)Payload)->json; +} + +/** + Fill the input RedPath string with system UUID from SMBIOS table or use the customized + ID if FromSmbios == FALSE. + + This is a helper function to build a RedPath string which can be used to address + a Redfish resource for this computer system. The input PathString must have a Systems + note in format of "Systems[UUID=%g]" or "Systems[UUID~%g]" to fill the UUID value. + + Example: + Use "/v1/Systems[UUID=%g]/Bios" to build a RedPath to address the "Bios" resource + for this computer system. + + @param[in] RedPath RedPath format to be build. + @param[in] FromSmbios Get system UUID from SMBIOS as computer system instance ID. + @param[in] IdString The computer system instance ID. + + @return Full RedPath with system UUID inside, or NULL if error happens. + +**/ +CHAR8 * +EFIAPI +RedfishBuildPathWithSystemUuid ( + IN CONST CHAR8 *RedPath, + IN BOOLEAN FromSmbios, + IN CHAR8 *IdString OPTIONAL + ) +{ + UINTN BufSize; + CHAR8* RetRedPath; + EFI_GUID SystemUuid; + EFI_STATUS Status; + + if (RedPath == NULL) { + return NULL; + } + + // + // Find system UUID from SMBIOS table. + // + if (FromSmbios) { + Status = NetLibGetSystemGuid(&SystemUuid); + if (EFI_ERROR (Status)) { + return NULL; + } + // AsciiStrLen ("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx") = 36 + BufSize = AsciiStrSize (RedPath) + AsciiStrLen ("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); + } else { + BufSize = AsciiStrSize (RedPath) + AsciiStrLen (IdString); + } + + RetRedPath = AllocateZeroPool (BufSize); + if (RetRedPath == NULL) { + return NULL; + } + if (FromSmbios) { + AsciiSPrint (RetRedPath, BufSize, RedPath, &SystemUuid); + } else { + AsciiSPrint (RetRedPath, BufSize, RedPath, IdString); + } + return RetRedPath; +} +/** + Get a redfish response addressed by a RedPath string, including HTTP StatusCode, Headers + and Payload which record any HTTP response messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] RedfishService The Service to access the Redfish resources. + @param[in] RedPath RedPath string to address a resource, must start + from the root node. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not + NULL and the value is 2XX. The corresponding redfish resource has + been returned in Payload within RedResponse. + @retval EFI_INVALID_PARAMETER RedfishService, RedPath, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned Payload is NULL, indicates any error happen. + 2. If the returned StatusCode is NULL, indicates any error happen. + 3. If the returned StatusCode is not 2XX, indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishGetByService ( + IN REDFISH_SERVICE RedfishService, + IN CONST CHAR8 *RedPath, + OUT REDFISH_RESPONSE *RedResponse + ) +{ + if (RedfishService == NULL || RedPath == NULL || RedResponse == NULL) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE)); + + RedResponse->Payload = (REDFISH_PAYLOAD) getPayloadByPath (RedfishService, RedPath, &(RedResponse->StatusCode)); + + // + // 1. If the returned Payload is NULL, indicates any error happen. + // 2. If the returned StatusCode is NULL, indicates any error happen. + // + if (RedResponse->Payload == NULL || RedResponse->StatusCode == NULL) { + return EFI_DEVICE_ERROR; + } + + // + // 3. If the returned StatusCode is not 2XX, indicates any error happen. + // NOTE: If there is any error message returned from server, it will be returned in + // Payload within RedResponse. + // + if (*(RedResponse->StatusCode) < HTTP_STATUS_200_OK || \ + *(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} +/** + Get a redfish response addressed by URI, including HTTP StatusCode, Headers + and Payload which record any HTTP response messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] RedfishService The Service to access the URI resources. + @param[in] Uri String to address a resource. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not + NULL and the value is 2XX. The corresponding redfish resource has + been returned in Payload within RedResponse. + @retval EFI_INVALID_PARAMETER RedfishService, RedPath, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned Payload is NULL, indicates any error happen. + 2. If the returned StatusCode is NULL, indicates any error happen. + 3. If the returned StatusCode is not 2XX, indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishGetByUri ( + IN REDFISH_SERVICE RedfishService, + IN CONST CHAR8 *Uri, + OUT REDFISH_RESPONSE *RedResponse + ) +{ + EDKII_JSON_VALUE JsonValue; + + if (RedfishService == NULL || Uri == NULL || RedResponse == NULL) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE)); + + JsonValue = getUriFromService (RedfishService, Uri, &RedResponse->StatusCode); + RedResponse->Payload = createRedfishPayload(JsonValue, RedfishService); + + // + // 1. If the returned Payload is NULL, indicates any error happen. + // 2. If the returned StatusCode is NULL, indicates any error happen. + // + if (RedResponse->Payload == NULL || RedResponse->StatusCode == NULL) { + return EFI_DEVICE_ERROR; + } + + // + // 3. If the returned StatusCode is not 2XX, indicates any error happen. + // NOTE: If there is any error message returned from server, it will be returned in + // Payload within RedResponse. + // + if (*(RedResponse->StatusCode) < HTTP_STATUS_200_OK || \ + *(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT) { + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; +} +/** + Get a redfish response addressed by the input Payload and relative RedPath string, + including HTTP StatusCode, Headers and Payload which record any HTTP response messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] Payload A existing REDFISH_PAYLOAD instance. + @param[in] RedPath Relative RedPath string to address a resource inside Payload. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful: + 1. The HTTP StatusCode is NULL and the returned Payload in + RedResponse is not NULL, indicates the Redfish resource has + been parsed from the input payload directly. + 2. The HTTP StatusCode is not NULL and the value is 2XX, + indicates the corresponding redfish resource has been returned + in Payload within RedResponse. + @retval EFI_INVALID_PARAMETER Payload, RedPath, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned Payload is NULL, indicates any error happen. + 2. If StatusCode is not NULL and the returned value of StatusCode + is not 2XX, indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishGetByPayload ( + IN REDFISH_PAYLOAD Payload, + IN CONST CHAR8 *RedPath, + OUT REDFISH_RESPONSE *RedResponse + ) +{ + if (Payload == NULL || RedPath == NULL || RedResponse == NULL) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE)); + + RedResponse->Payload = (REDFISH_PAYLOAD) getPayloadForPathString (Payload, RedPath, &(RedResponse->StatusCode)); + + // + // 1. If the returned Payload is NULL, indicates any error happen. + // + if (RedResponse->Payload == NULL) { + return EFI_DEVICE_ERROR; + } + + // + // 2. If StatusCode is not NULL and the returned value of StatusCode is not 2XX, indicates any + // error happen. + // NOTE: If there is any error message returned from server, it will be returned in + // Payload within RedResponse. + // + if (RedResponse->StatusCode != NULL && \ + (*(RedResponse->StatusCode) < HTTP_STATUS_200_OK || \ + *(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT + )) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} +/** + Use HTTP PATCH to perform updates on pre-existing Redfish resource. + + This function uses the RedfishService to patch a Redfish resource addressed by + Uri (only the relative path is required). Changes to one or more properties within + the target resource are represented in the input Content, properties not specified + in Content won't be changed by this request. The corresponding redfish response will + returned, including HTTP StatusCode, Headers and Payload which record any HTTP response + messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] RedfishService The Service to access the Redfish resources. + @param[in] Uri Relative path to address the resource. + @param[in] Content JSON represented properties to be update. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not + NULL and the value is 2XX. The Redfish resource will be returned + in Payload within RedResponse if server send it back in the HTTP + response message body. + @retval EFI_INVALID_PARAMETER RedfishService, Uri, Content, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned StatusCode is NULL, indicates any error happen. + 2. If the returned StatusCode is not NULL and the value is not 2XX, + indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishPatchToUri ( + IN REDFISH_SERVICE RedfishService, + IN CONST CHAR8 *Uri, + IN CONST CHAR8 *Content, + OUT REDFISH_RESPONSE *RedResponse + ) +{ + EFI_STATUS Status; + EDKII_JSON_VALUE JsonValue; + + Status = EFI_SUCCESS; + JsonValue = NULL; + + if (RedfishService == NULL || Uri == NULL || Content == NULL || RedResponse == NULL) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE)); + + JsonValue = (EDKII_JSON_VALUE) patchUriFromService ( + RedfishService, + Uri, + Content, + &(RedResponse->StatusCode) + ); + + // + // 1. If the returned StatusCode is NULL, indicates any error happen. + // + if (RedResponse->StatusCode == NULL) { + Status = EFI_DEVICE_ERROR; + goto ON_EXIT; + } + + // + // 2. If the returned StatusCode is not NULL and the value is not 2XX, indicates any error happen. + // NOTE: If there is any error message returned from server, it will be returned in + // Payload within RedResponse. + // + if (*(RedResponse->StatusCode) < HTTP_STATUS_200_OK || \ + *(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT) { + Status = EFI_DEVICE_ERROR; + } + +ON_EXIT: + if (JsonValue != NULL) { + RedResponse->Payload = createRedfishPayload (JsonValue, RedfishService); + if (RedResponse->Payload == NULL) { + // + // Ignore the error when create RedfishPayload, just free the JsonValue since it's not what + // we care about if the returned StatusCode is 2XX. + // + JsonValueFree (JsonValue); + } + } + + return Status; +} +/** + Use HTTP PATCH to perform updates on target payload. Patch to odata.id in Payload directly. + + This function uses the Payload to patch the Target. Changes to one or more properties + within the target resource are represented in the input Payload, properties not specified + in Payload won't be changed by this request. The corresponding redfish response will + returned, including HTTP StatusCode, Headers and Payload which record any HTTP response + messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] Target The target payload to be updated. + @param[in] Payload Palyoad with properties to be changed. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not + NULL and the value is 2XX. The Redfish resource will be returned + in Payload within RedResponse if server send it back in the HTTP + response message body. + @retval EFI_INVALID_PARAMETER Target, Payload, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned StatusCode is NULL, indicates any error happen. + 2. If the returned StatusCode is not NULL and the value is not 2XX, + indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishPatchToPayload ( + IN REDFISH_PAYLOAD Target, + IN REDFISH_PAYLOAD Payload, + OUT REDFISH_RESPONSE *RedResponse + ) +{ + if (Target == NULL || Payload == NULL || RedResponse == NULL) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE)); + + RedResponse->Payload = (REDFISH_PAYLOAD) patchPayload ( + Target, + Payload, + &(RedResponse->StatusCode) + ); + + // + // 1. If the returned StatusCode is NULL, indicates any error happen. + // + if (RedResponse->StatusCode == NULL) { + return EFI_DEVICE_ERROR; + } + + // + // 2. If the returned StatusCode is not NULL and the value is not 2XX, indicates any error happen. + // NOTE: If there is any error message returned from server, it will be returned in + // Payload within RedResponse. + // + if (*(RedResponse->StatusCode) < HTTP_STATUS_200_OK || \ + *(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} +/** + Use HTTP POST to create a new resource in target payload. + + The POST request should be submitted to the Resource Collection in which the new resource + is to belong. The Resource Collection is addressed by Target payload. The Redfish may + ignore any service controlled properties. The corresponding redfish response will returned, + including HTTP StatusCode, Headers and Payload which record any HTTP response messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] Target Target payload of the Resource Collection. + @param[in] Payload The new resource to be created. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not + NULL and the value is 2XX. The Redfish resource will be returned + in Payload within RedResponse if server send it back in the HTTP + response message body. + @retval EFI_INVALID_PARAMETER Target, Payload, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned StatusCode is NULL, indicates any error happen. + 2. If the returned StatusCode is not NULL and the value is not 2XX, + indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishPostToPayload ( + IN REDFISH_PAYLOAD Target, + IN REDFISH_PAYLOAD Payload, + OUT REDFISH_RESPONSE *RedResponse + ) +{ + if (Target == NULL || Payload == NULL || RedResponse == NULL) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE)); + + RedResponse->Payload = (REDFISH_PAYLOAD) postPayload ( + Target, + Payload, + &(RedResponse->StatusCode) + ); + + // + // 1. If the returned StatusCode is NULL, indicates any error happen. + // + if (RedResponse->StatusCode == NULL) { + return EFI_DEVICE_ERROR; + } + + // + // 2. If the returned StatusCode is not NULL and the value is not 2XX, indicates any error happen. + // NOTE: If there is any error message returned from server, it will be returned in + // Payload within RedResponse. + // + if (*(RedResponse->StatusCode) < HTTP_STATUS_200_OK || \ + *(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} +/** + Use HTTP DELETE to remove a resource. + + This function uses the RedfishService to remove a Redfish resource which is addressed + by input Uri (only the relative path is required). The corresponding redfish response will + returned, including HTTP StatusCode, Headers and Payload which record any HTTP response + messages. + + Callers are responsible for freeing the HTTP StatusCode, Headers and Payload returned in + redfish response data. + + @param[in] RedfishService The Service to access the Redfish resources. + @param[in] Uri Relative path to address the resource. + @param[out] RedResponse Pointer to the Redfish response data. + + @retval EFI_SUCCESS The opeartion is successful, indicates the HTTP StatusCode is not + NULL and the value is 2XX, the Redfish resource has been removed. + If there is any message returned from server, it will be returned + in Payload within RedResponse. + @retval EFI_INVALID_PARAMETER RedfishService, Uri, or RedResponse is NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. Callers can get + more error info from returned HTTP StatusCode, Headers and Payload + within RedResponse: + 1. If the returned StatusCode is NULL, indicates any error happen. + 2. If the returned StatusCode is not NULL and the value is not 2XX, + indicates any error happen. +**/ +EFI_STATUS +EFIAPI +RedfishDeleteByUri ( + IN REDFISH_SERVICE RedfishService, + IN CONST CHAR8 *Uri, + OUT REDFISH_RESPONSE *RedResponse + ) +{ + EFI_STATUS Status; + EDKII_JSON_VALUE JsonValue; + + Status = EFI_SUCCESS; + JsonValue = NULL; + + if (RedfishService == NULL || Uri == NULL || RedResponse == NULL) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (RedResponse, sizeof (REDFISH_RESPONSE)); + + JsonValue = (EDKII_JSON_VALUE) deleteUriFromService ( + RedfishService, + Uri, + &(RedResponse->StatusCode) + ); + + // + // 1. If the returned StatusCode is NULL, indicates any error happen. + // + if (RedResponse->StatusCode == NULL) { + Status = EFI_DEVICE_ERROR; + goto ON_EXIT; + } + + // + // 2. If the returned StatusCode is not NULL and the value is not 2XX, indicates any error happen. + // NOTE: If there is any error message returned from server, it will be returned in + // Payload within RedResponse. + // + if (*(RedResponse->StatusCode) < HTTP_STATUS_200_OK || \ + *(RedResponse->StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT) { + Status = EFI_DEVICE_ERROR; + } + +ON_EXIT: + if (JsonValue != NULL) { + RedResponse->Payload = createRedfishPayload (JsonValue, RedfishService); + if (RedResponse->Payload == NULL) { + // + // Ignore the error when create RedfishPayload, just free the JsonValue since it's not what + // we care about if the returned StatusCode is 2XX. + // + JsonValueFree (JsonValue); + } + } + + return Status; +} +/** + Dump text in fractions. + + @param[in] String ASCII string to dump. + +**/ +VOID +RedfishDumpJsonStringFractions ( + IN CHAR8 *String + ) +{ + CHAR8 *NextFraction; + UINTN StringFractionSize; + UINTN StrLen; + UINTN Count; + CHAR8 BackupChar; + + StringFractionSize = 200; + if (String == NULL) { + return ; + } + + DEBUG((DEBUG_INFO, "JSON text:\n")); + NextFraction = String; + StrLen = AsciiStrLen (String); + if (StrLen == 0) { + return; + } + for (Count = 0; Count < (StrLen / StringFractionSize); Count++) { + BackupChar = *(NextFraction + StringFractionSize); + *(NextFraction + StringFractionSize) = 0; + DEBUG((DEBUG_INFO, "%a", NextFraction)); + *(NextFraction + StringFractionSize) = BackupChar; + NextFraction += StringFractionSize; + } + if ((StrLen % StringFractionSize) != 0) { + DEBUG((DEBUG_INFO, "%a\n\n", NextFraction)); + } +} +/** + Dump text in JSON value. + + @param[in] JsonValue The Redfish JSON value to dump. + +**/ +VOID +RedfishDumpJson ( + IN EDKII_JSON_VALUE JsonValue + ) +{ + CHAR8 *String; + + String = JsonDumpString (JsonValue, 0); + if (String == NULL) { + return; + } + RedfishDumpJsonStringFractions (String); + FreePool(String); +} +/** + Extract the JSON text content from REDFISH_PAYLOAD and dump to debug console. + + @param[in] Payload The Redfish payload to dump. + +**/ +VOID +RedfishDumpPayload ( + IN REDFISH_PAYLOAD Payload + ) +{ + EDKII_JSON_VALUE JsonValue; + CHAR8 *String; + + JsonValue = NULL; + String = NULL; + + if (Payload == NULL) { + return; + } + + JsonValue = RedfishJsonInPayload (Payload); + if (JsonValue == NULL) { + return; + } + + String = JsonDumpString (JsonValue, 0); + if (String == NULL) { + return; + } + + RedfishDumpJsonStringFractions (String); + FreePool(String); +} +/** + This function will cleanup the HTTP header and Redfish payload resources. + + @param[in] StatusCode The status code in HTTP response message. + @param[in] HeaderCount Number of HTTP header structures in Headers list. + @param[in] Headers Array containing list of HTTP headers. + @param[in] Payload The Redfish payload to dump. + +**/ +VOID +RedfishFreeResponse ( + IN EFI_HTTP_STATUS_CODE *StatusCode, + IN UINTN HeaderCount, + IN EFI_HTTP_HEADER *Headers, + IN REDFISH_PAYLOAD Payload + ) +{ + if (StatusCode != NULL) { + FreePool (StatusCode); + StatusCode = NULL; + } + + if (HeaderCount != 0 && Headers != NULL) { + HttpFreeHeaderFields(Headers, HeaderCount); + Headers = NULL; + } + + if (Payload != NULL) { + RedfishCleanupPayload (Payload); + Payload = NULL; + } +} +/** + Check if the "@odata.type" in Payload is valid or not. + + @param[in] Payload The Redfish payload to be checked. + @param[in] OdataTypeName OdataType will be retrived from mapping list. + @param[in] OdataTypeMappingList The list of OdataType. + @param[in] OdataTypeMappingListSize The number of mapping list + + @return TRUE if the "@odata.type" in Payload is valid, otherwise FALSE. + +**/ +BOOLEAN +RedfishIsValidOdataType ( + IN REDFISH_PAYLOAD Payload, + IN CONST CHAR8 *OdataTypeName, + IN REDFISH_ODATA_TYPE_MAPPING *OdataTypeMappingList, + IN UINTN OdataTypeMappingListSize + ) +{ + UINTN Index; + EDKII_JSON_VALUE OdataType; + EDKII_JSON_VALUE JsonValue; + + if (Payload == NULL || OdataTypeName == NULL) { + return FALSE; + } + + JsonValue = RedfishJsonInPayload (Payload); + if (!JsonValueIsObject (JsonValue)) { + return FALSE; + } + + OdataType = JsonObjectGetValue (JsonValueGetObject (JsonValue), "@odata.type"); + if (!JsonValueIsString (OdataType) || JsonValueGetAsciiString (OdataType) == NULL) { + return FALSE; + } + + for (Index = 0; Index < OdataTypeMappingListSize; Index ++) { + if (AsciiStrCmp (OdataTypeMappingList[Index].OdataTypeName, OdataTypeName) == 0 && + AsciiStrCmp (OdataTypeMappingList[Index].OdataType, JsonValueGetAsciiString (OdataType)) == 0) { + return TRUE; + } + } + DEBUG ((DEBUG_INFO, "%a: This Odata type is not in the list.\n", __FUNCTION__)); + return FALSE; +} +/** + Check if the payload is collection + + @param[in] Payload The Redfish payload to be checked. + + @return TRUE if the payload is collection. + +**/ +BOOLEAN +RedfishIsPayloadCollection ( + IN REDFISH_PAYLOAD Payload +) +{ + return isPayloadCollection (Payload); +} +/** + Get collection size. + + @param[in] Payload The Redfish collection payload + @param[in] CollectionSize Size of this collection + + @return EFI_SUCCESS Coolection size is returned in CollectionSize + @return EFI_INVALID_PARAMETER The payload is not a collection. +**/ +EFI_STATUS +RedfishGetCollectionSize( + IN REDFISH_PAYLOAD Payload, + IN UINTN *CollectionSize + ) +{ + if (Payload == NULL || CollectionSize == NULL) { + return EFI_INVALID_PARAMETER; + } + if (!RedfishIsPayloadCollection(Payload)) { + return EFI_INVALID_PARAMETER; + } + + *CollectionSize = (UINTN)getCollectionSize(Payload); + return EFI_SUCCESS; +} +/** + Get Redfish payload of collection member + + @param[in] Payload The Redfish collection payload + @param[in] Index Index of collection member + + @return NULL Fail to get collection member. + @return Non NULL Payload is returned. +**/ +REDFISH_PAYLOAD +RedfishGetPayloadByIndex ( + IN REDFISH_PAYLOAD Payload, + IN UINTN Index +) +{ + REDFISH_RESPONSE RedfishResponse; + REDFISH_PAYLOAD PayloadReturn; + + PayloadReturn = (VOID *)getPayloadByIndex (Payload, Index, &RedfishResponse.StatusCode); + if(PayloadReturn == NULL || + (*(RedfishResponse.StatusCode) < HTTP_STATUS_200_OK && *(RedfishResponse.StatusCode) > HTTP_STATUS_206_PARTIAL_CONTENT)){ + return NULL; + } + return PayloadReturn; +} +/** + Check and return Redfish resource of the given Redpath. + + @param[in] RedfishService Pointer to REDFISH_SERVICE + @param[in] Redpath Redpath of the resource. + @param[in] Response Optional return the resource. + + @return EFI_STATUS +**/ +EFI_STATUS +RedfishCheckIfRedpathExist ( + IN REDFISH_SERVICE RedfishService, + IN CHAR8 *Redpath, + IN REDFISH_RESPONSE *Response OPTIONAL + ) +{ + EFI_STATUS Status; + REDFISH_RESPONSE TempResponse; + + if (Redpath == NULL) { + return EFI_INVALID_PARAMETER; + } + Status = RedfishGetByService (RedfishService, Redpath, &TempResponse); + if (EFI_ERROR (Status)) { + return Status; + } + if (Response == NULL) { + RedfishFreeResponse( + TempResponse.StatusCode, + TempResponse.HeaderCount, + TempResponse.Headers, + TempResponse.Payload + ); + } else { + CopyMem ((VOID *)Response, (VOID *)&TempResponse, sizeof (REDFISH_RESPONSE)); + } + return EFI_SUCCESS; +} diff --git a/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/RedfishLib.inf b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/RedfishLib.inf new file mode 100644 index 00000000000..6afabd6d132 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/RedfishLib.inf @@ -0,0 +1,60 @@ +## @file +# RedfishLib Library implementation. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001b + BASE_NAME = DxeRedfishLib + FILE_GUID = 9C2CA9CF-4F79-11E8-A7D1-8CDCD426C973 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = RedfishLib| DXE_DRIVER UEFI_APPLICATION UEFI_DRIVER + +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64 +# + +[Sources] + edk2libredfish/src/redpath.c + edk2libredfish/src/service.c + edk2libredfish/src/payload.c + edk2libredfish/include/redfish.h + edk2libredfish/include/redfishPayload.h + edk2libredfish/include/redfishService.h + edk2libredfish/include/redpath.h + RedfishLib.c + RedfishMisc.h + RedfishMisc.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + NetworkPkg/NetworkPkg.dec + RedfishPkg/RedfishPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + HttpLib + MemoryAllocationLib + NetLib + RedfishContentCodingLib + RedfishCrtLib + UefiBootServicesTableLib + UefiLib + +[Protocols] + gEfiRestExServiceBindingProtocolGuid ## Consumed + gEfiRestExProtocolGuid ## Consumed + gEdkIIRedfishCredentialProtocolGuid ## Consumed + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /U_WIN32 /UWIN64 /U_MSC_VER + GCC:*_*_*_CC_FLAGS = -Wno-unused-function -Wno-unused-but-set-variable diff --git a/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/RedfishMisc.c b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/RedfishMisc.c new file mode 100644 index 00000000000..324811532e2 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/RedfishMisc.c @@ -0,0 +1,201 @@ +/** @file + Internal Functions for RedfishLib. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "RedfishMisc.h" + +EDKII_REDFISH_CREDENTIAL_PROTOCOL *mCredentialProtocol = NULL; + +/** + This function returns the string of Redfish service version. + + @param[in] RedfishService Redfish service instance. + @param[out] ServiceVersionStr Redfish service string. + + @return EFI_STATUS + +**/ +EFI_STATUS +RedfishGetServiceVersion ( + IN REDFISH_SERVICE RedfishService, + OUT CHAR8 **ServiceVersionStr + ) +{ + redfishService *Redfish; + CHAR8 **KeysArray; + UINTN KeysNum; + + if (RedfishService == NULL || ServiceVersionStr == NULL) { + return EFI_INVALID_PARAMETER; + } + Redfish = (redfishService *)RedfishService; + if (Redfish->versions == NULL) { + return EFI_INVALID_PARAMETER; + } + KeysArray = JsonObjectGetKeys (Redfish->versions, &KeysNum); + if (KeysNum == 0 || KeysArray == NULL) { + return EFI_NOT_FOUND; + } + *ServiceVersionStr = *KeysArray; + return EFI_SUCCESS; +} + +/** + Creates a REDFISH_SERVICE which can be later used to access the Redfish resources. + + This function will configure REST EX child according to parameters described in + Redfish network host interface in SMBIOS type 42 record. The service enumerator will also + handle the authentication flow automatically if HTTP basic auth or Redfish session + login is configured to use. + + @param[in] RedfishConfigServiceInfo Redfish service information the EFI Redfish + feature driver communicates with. + @param[in] AuthMethod None, HTTP basic auth, or Redfish session login. + @param[in] UserId User Name used for authentication. + @param[in] Password Password used for authentication. + + @return New created Redfish service, or NULL if error happens. + +**/ +REDFISH_SERVICE +RedfishCreateLibredfishService ( + IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo, + IN EDKII_REDFISH_AUTH_METHOD AuthMethod, + IN CHAR8 *UserId, + IN CHAR8 *Password + ) +{ + + UINTN Flags; + enumeratorAuthentication Auth; + redfishService* Redfish; + + Redfish = NULL; + + ZeroMem (&Auth, sizeof (Auth)); + if (AuthMethod == AuthMethodHttpBasic) { + Auth.authType = REDFISH_AUTH_BASIC; + } else if (AuthMethod == AuthMethodRedfishSession) { + Auth.authType = REDFISH_AUTH_SESSION; + } + Auth.authCodes.userPass.username = UserId; + Auth.authCodes.userPass.password = Password; + + Flags = REDFISH_FLAG_SERVICE_NO_VERSION_DOC; + + if (AuthMethod != AuthMethodNone) { + Redfish = createServiceEnumerator(RedfishConfigServiceInfo, NULL, &Auth, (unsigned int ) Flags); + } else { + Redfish = createServiceEnumerator(RedfishConfigServiceInfo, NULL, NULL, (unsigned int) Flags); + } + + // + // Zero the Password after use. + // + if (Password != NULL) { + ZeroMem (Password, AsciiStrLen(Password)); + } + + return (REDFISH_SERVICE) Redfish; +} + +/** + Retrieve platform's Redfish authentication information. + + This functions returns the Redfish authentication method together with the user + Id and password. + For AuthMethodNone, UserId and Password will point to NULL which means authentication + is not required to access the Redfish service. + For AuthMethodHttpBasic, the UserId and Password could be used for + HTTP header authentication as defined by RFC7235. For AuthMethodRedfishSession, + the UserId and Password could be used for Redfish session login as defined by + Redfish API specification (DSP0266). + + Callers are responsible for freeing the returned string storage pointed by UserId + and Password. + + @param[out] AuthMethod Type of Redfish authentication method. + @param[out] UserId The pointer to store the returned UserId string. + @param[out] Password The pointer to store the returned Password string. + + @retval EFI_SUCCESS Get the authentication information successfully. + @retval EFI_INVALID_PARAMETER AuthMethod or UserId or Password is NULL. + @retval EFI_UNSUPPORTED Unsupported authentication method is found. +**/ +EFI_STATUS +RedfishGetAuthInfo ( + OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod, + OUT CHAR8 **UserId, + OUT CHAR8 **Password + ) +{ + EFI_STATUS Status; + + if (AuthMethod == NULL || UserId == NULL || Password == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Locate Redfish Credential Protocol. + // + if (mCredentialProtocol == NULL) { + Status = gBS->LocateProtocol (&gEdkIIRedfishCredentialProtocolGuid, NULL, (VOID **)&mCredentialProtocol); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + } + + ASSERT (mCredentialProtocol != NULL); + + Status = mCredentialProtocol->GetAuthInfo (mCredentialProtocol, AuthMethod, UserId, Password); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "RedfishGetAuthInfo: failed to retrieve Redfish credential - %r\n", Status)); + return Status; + } + + return Status; +} +/** + This function returns the string of Redfish service version. + + @param[in] ServiceVerisonStr The string of Redfish service version. + @param[in] Url The URL to build Redpath with ID. + Start with "/", for example "/Registries" + @param[in] Id ID string + @param[out] Redpath Pointer to retrive Redpath, caller has to free + the memory allocated for this string. + @return EFI_STATUS + +**/ +EFI_STATUS +RedfishBuildRedpathUseId ( + IN CHAR8 *ServiceVerisonStr, + IN CHAR8 *Url, + IN CHAR8 *Id, + OUT CHAR8 **Redpath + ) +{ + UINTN RedpathSize; + + if (Redpath == NULL || ServiceVerisonStr == NULL || Url == NULL || Id == NULL) { + return EFI_INVALID_PARAMETER; + } + + RedpathSize = AsciiStrLen ("/") + + AsciiStrLen (ServiceVerisonStr) + + AsciiStrLen (Url) + + AsciiStrLen ("[Id=]") + + AsciiStrLen (Id) + 1; + *Redpath = AllocatePool(RedpathSize); + if (*Redpath == NULL) { + return EFI_OUT_OF_RESOURCES; + } + AsciiSPrint (*Redpath, RedpathSize, "/%a%a[Id=%a]", ServiceVerisonStr, Url, Id); + return EFI_SUCCESS; +} diff --git a/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/RedfishMisc.h b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/RedfishMisc.h new file mode 100644 index 00000000000..19710398663 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/RedfishMisc.h @@ -0,0 +1,82 @@ +/** @file + Internal Functions for RedfishLib. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef DXE_REDFISH_MISC_LIB_H_ +#define DXE_REDFISH_MISC_LIB_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ARRAY_SIZE(Array) (sizeof (Array) / sizeof ((Array)[0])) + +/** + Creates a REDFISH_SERVICE which can be later used to access the Redfish resources. + + This function will configure REST EX child according to parameters described in + Redfish network host interface in SMBIOS type 42 record. The service enumerator will also + handle the authentication flow automatically if HTTP basic auth or Redfish session + login is configured to use. + + @param[in] RedfishConfigServiceInfo Redfish service information the EFI Redfish + feature driver communicates with. + @param[in] AuthMethod None, HTTP basic auth, or Redfish session login. + @param[in] UserId User Name used for authentication. + @param[in] Password Password used for authentication. + + @return New created Redfish service, or NULL if error happens. + +**/ +REDFISH_SERVICE +RedfishCreateLibredfishService ( + IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo, + IN EDKII_REDFISH_AUTH_METHOD AuthMethod, + IN CHAR8 *UserId, + IN CHAR8 *Password + ); + +/** + Retrieve platform's Redfish authentication information. + + This functions returns the Redfish authentication method together with the user + Id and password. + For AuthMethodNone, UserId and Password will point to NULL which means authentication + is not required to access the Redfish service. + For AuthMethodHttpBasic, the UserId and Password could be used for + HTTP header authentication as defined by RFC7235. For AuthMethodRedfishSession, + the UserId and Password could be used for Redfish session login as defined by + Redfish API specification (DSP0266). + + Callers are responsible for freeing the returned string storage pointed by UserId + and Password. + + @param[out] AuthMethod Type of Redfish authentication method. + @param[out] UserId The pointer to store the returned UserId string. + @param[out] Password The pointer to store the returned Password string. + + @retval EFI_SUCCESS Get the authentication information successfully. + @retval EFI_INVALID_PARAMETER AuthMethod or UserId or Password is NULL. + @retval EFI_UNSUPPORTED Unsupported authentication method is found. +**/ +EFI_STATUS +RedfishGetAuthInfo ( + OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod, + OUT CHAR8 **UserId, + OUT CHAR8 **Password + ); + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfish.h b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfish.h new file mode 100644 index 00000000000..5804379b1e7 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfish.h @@ -0,0 +1,24 @@ +/** @file + This file is cloned from DMTF libredfish library tag v1.0.0 and maintained + by EDKII. + +//---------------------------------------------------------------------------- +// Copyright Notice: +// Copyright 2017 Distributed Management Task Force, Inc. All rights reserved. +// License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libredfish/LICENSE.md +//---------------------------------------------------------------------------- + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef LIBREDFISH_REDFISH_H_ +#define LIBREDFISH_REDFISH_H_ + +#include +#include +#include + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfishPayload.h b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfishPayload.h new file mode 100644 index 00000000000..83c6cd60340 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfishPayload.h @@ -0,0 +1,39 @@ +/** @file + This file is cloned from DMTF libredfish library tag v1.0.0 and maintained + by EDKII. + +//---------------------------------------------------------------------------- +// Copyright Notice: +// Copyright 2017 Distributed Management Task Force, Inc. All rights reserved. +// License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libredfish/LICENSE.md +//---------------------------------------------------------------------------- + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef LIBREDFISH_REDFISH_PAYLOAD_H_ +#define LIBREDFISH_REDFISH_PAYLOAD_H_ + +#include + +#include +#include +#include + +redfishPayload* createRedfishPayload(json_t* value, redfishService* service); +redfishPayload* getPayloadByNodeName(redfishPayload* payload, const char* nodeName, EFI_HTTP_STATUS_CODE** StatusCode); +redfishPayload* getPayloadByIndex(redfishPayload* payload, size_t index, EFI_HTTP_STATUS_CODE** StatusCode); +redfishPayload* getPayloadForPath(redfishPayload* payload, redPathNode* redpath, EFI_HTTP_STATUS_CODE** StatusCode); +redfishPayload* getPayloadForPathString(redfishPayload* payload, const char* string, EFI_HTTP_STATUS_CODE** StatusCode); +redfishPayload* patchPayload(redfishPayload* target, redfishPayload* payload, EFI_HTTP_STATUS_CODE** StatusCode); +redfishPayload* postContentToPayload(redfishPayload* target, const char* data, size_t dataSize, const char* contentType, EFI_HTTP_STATUS_CODE** StatusCode); +redfishPayload* postPayload(redfishPayload* target, redfishPayload* payload, EFI_HTTP_STATUS_CODE** StatusCode); +void cleanupPayload(redfishPayload* payload); +bool isPayloadCollection (redfishPayload *Payload); +size_t getCollectionSize(redfishPayload* payload); +redfishPayload* getPayloadByIndex (redfishPayload* payload, size_t index, EFI_HTTP_STATUS_CODE** StatusCode); + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfishService.h b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfishService.h new file mode 100644 index 00000000000..d6bc4a8dd3d --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redfishService.h @@ -0,0 +1,101 @@ +/** @file + This file is cloned from DMTF libredfish library tag v1.0.0 and maintained + by EDKII. + +//---------------------------------------------------------------------------- +// Copyright Notice: +// Copyright 2017 Distributed Management Task Force, Inc. All rights reserved. +// License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libredfish/LICENSE.md +//---------------------------------------------------------------------------- + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef LIBREDFISH_REDFISH_SERVICE_H_ +#define LIBREDFISH_REDFISH_SERVICE_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +typedef struct { + char* host; + json_t* versions; + unsigned int flags; + char* sessionToken; + char* basicAuthStr; + // + // point to the part in above "host" field, which will be put into + // the "Host" header of HTTP request message. + // + char* HostHeaderValue; + EFI_REST_EX_PROTOCOL *RestEx; +} redfishService; + +typedef struct { + json_t* json; + redfishService* service; +} redfishPayload; + +#define REDFISH_AUTH_BASIC 0 +#define REDFISH_AUTH_BEARER_TOKEN 1 +#define REDFISH_AUTH_SESSION 2 + +#define REDFISH_HTTP_RESPONSE_TIMEOUT 5000 /// 5 seconds in uints of millisecond. + +/// +/// Library class public defines +/// +#define HTTP_FLAG L"http://" +#define HTTPS_FLAG L"https://" + +/// +/// The redfish first URL should be "/redfish/v1/", while we use "/redfish/v1" here without "/" +/// in the end is to avoid the 301 Perment redirect response from Redfish profile simulator. +/// +#define REDFISH_FIRST_URL L"/redfish/v1" + +typedef struct { + unsigned int authType; + union { + struct { + char* username; + char* password; + } userPass; + struct { + char* token; + } authToken; + } authCodes; +} enumeratorAuthentication; + +//Values for flags +#define REDFISH_FLAG_SERVICE_NO_VERSION_DOC 0x00000001 //The Redfish Service lacks the version document (in violation of the Redfish spec) +redfishService* createServiceEnumerator(REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo, const char* rootUri, enumeratorAuthentication* auth, unsigned int flags); +json_t* getUriFromService(redfishService* service, const char* uri, EFI_HTTP_STATUS_CODE** StatusCode); +json_t* patchUriFromService(redfishService* service, const char* uri, const char* content, EFI_HTTP_STATUS_CODE** StatusCode); +json_t* postUriFromService(redfishService* service, const char* uri, const char* content, size_t contentLength, const char* contentType, EFI_HTTP_STATUS_CODE** StatusCode); +json_t* deleteUriFromService(redfishService* service, const char* uri, EFI_HTTP_STATUS_CODE** StatusCode); +redfishPayload* getRedfishServiceRoot(redfishService* service, const char* version, EFI_HTTP_STATUS_CODE** StatusCode); +redfishPayload* getPayloadByPath(redfishService* service, const char* path, EFI_HTTP_STATUS_CODE** StatusCode); +void cleanupServiceEnumerator(redfishService* service); + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redpath.h b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redpath.h new file mode 100644 index 00000000000..a9a3538f19a --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/include/redpath.h @@ -0,0 +1,42 @@ +/** @file + This file is cloned from DMTF libredfish library tag v1.0.0 and maintained + by EDKII. + +//---------------------------------------------------------------------------- +// Copyright Notice: +// Copyright 2017 Distributed Management Task Force, Inc. All rights reserved. +// License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libredfish/LICENSE.md +//---------------------------------------------------------------------------- + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef LIBREDFISH_REDPATH_H_ +#define LIBREDFISH_REDPATH_H_ + +#include + +#include + +typedef struct _redPathNode +{ + bool isRoot; + bool isIndex; + + char* version; + char* nodeName; + size_t index; + char* op; + char* propName; + char* value; + + struct _redPathNode* next; +} redPathNode; + +redPathNode* parseRedPath(const char* path); +void cleanupRedPath(redPathNode* node); + +#endif diff --git a/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/payload.c b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/payload.c new file mode 100644 index 00000000000..f9f2294eff6 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/payload.c @@ -0,0 +1,732 @@ +/** @file + This file is cloned from DMTF libredfish library tag v1.0.0 and maintained + by EDKII. + +//---------------------------------------------------------------------------- +// Copyright Notice: +// Copyright 2017 Distributed Management Task Force, Inc. All rights reserved. +// License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libredfish/LICENSE.md +//---------------------------------------------------------------------------- + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include + +static redfishPayload* getOpResult(redfishPayload* payload, const char* propName, const char* op, const char* value, EFI_HTTP_STATUS_CODE** StatusCode); +static redfishPayload* collectionEvalOp(redfishPayload* payload, const char* propName, const char* op, const char* value, EFI_HTTP_STATUS_CODE** StatusCode); +static redfishPayload* arrayEvalOp(redfishPayload* payload, const char* propName, const char* op, const char* value, EFI_HTTP_STATUS_CODE** StatusCode); +static redfishPayload* createCollection(redfishService* service, size_t count, redfishPayload** payloads); +static json_t* json_object_get_by_index(json_t* json, size_t index); + +bool isPayloadCollection(redfishPayload* payload) +{ + json_t* members; + json_t* count; + + if(!payload || !json_is_object(payload->json)) + { + return false; + } + members = json_object_get(payload->json, "Members"); + count = json_object_get(payload->json, "Members@odata.count"); + return ((members != NULL) && (count != NULL)); +} + +size_t getCollectionSize(redfishPayload* payload) +{ + json_t* members; + json_t* count; + + if(!payload || !json_is_object(payload->json)) + { + return 0; + } + members = json_object_get(payload->json, "Members"); + count = json_object_get(payload->json, "Members@odata.count"); + if(!members || !count) + { + return 0; + } + return (size_t)json_integer_value(count); +} + +bool isPayloadArray(redfishPayload* payload) +{ + if(!payload || !json_is_array(payload->json)) + { + return false; + } + return true; +} + +char* payloadToString(redfishPayload* payload, bool prettyPrint) +{ + size_t flags = 0; + if(!payload) + { + return NULL; + } + if(prettyPrint) + { + flags = JSON_INDENT(2); + } + return json_dumps(payload->json, flags); +} + +redfishPayload* createRedfishPayload(json_t* value, redfishService* service) +{ + redfishPayload* payload; + payload = (redfishPayload*)malloc(sizeof(redfishPayload)); + if(payload != NULL) + { + payload->json = value; + payload->service = service; + } + return payload; +} + +redfishPayload* getPayloadByNodeName(redfishPayload* payload, const char* nodeName, EFI_HTTP_STATUS_CODE** StatusCode) +{ + json_t* value; + json_t* odataId; + const char* uri; + + if(!payload || !nodeName || StatusCode == NULL) + { + return NULL; + } + + *StatusCode = NULL; + + value = json_object_get(payload->json, nodeName); + if(value == NULL) + { + return NULL; + } + json_incref(value); + if(json_object_size(value) == 1) + { + odataId = json_object_get(value, "@odata.id"); + if(odataId != NULL) + { + json_incref(odataId); + uri = json_string_value(odataId); + json_decref(value); + value = getUriFromService(payload->service, uri, StatusCode); + json_decref(odataId); + if(value == NULL || *StatusCode == NULL) + { + return NULL; + } + } + } + if (*StatusCode == NULL || (**StatusCode >= HTTP_STATUS_200_OK && **StatusCode <= HTTP_STATUS_206_PARTIAL_CONTENT)) { + if(json_is_string(value)) + { + odataId = json_object(); + json_object_set(odataId, nodeName, value); + json_decref(value); + value = odataId; + } + } + + return createRedfishPayload(value, payload->service); +} + +redfishPayload* getPayloadByIndex(redfishPayload* payload, size_t index, EFI_HTTP_STATUS_CODE** StatusCode) +{ + json_t* value = NULL; + json_t* odataId; + const char* uri; + BOOLEAN FromServerFlag = FALSE; + + if(!payload || StatusCode == NULL) + { + return NULL; + } + + *StatusCode = NULL; + + if(isPayloadCollection(payload)) + { + redfishPayload* members = getPayloadByNodeName(payload, "Members", StatusCode); + if ((*StatusCode == NULL && members == NULL) || + (*StatusCode != NULL && (**StatusCode < HTTP_STATUS_200_OK || **StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))) { + return members; + } + + if (*StatusCode != NULL) { + // + // The Payload (members) are retrived from server. + // + FreePool (*StatusCode); + *StatusCode = NULL; + FromServerFlag = TRUE; + } + + redfishPayload* ret = getPayloadByIndex(members, index, StatusCode); + if (*StatusCode == NULL && ret != NULL && FromServerFlag) { + // + // In such a case, the Redfish resource is parsed from the input payload (members) directly. + // Since the members are retrived from server, we still return HTTP_STATUS_200_OK. + // + *StatusCode = AllocateZeroPool (sizeof (EFI_HTTP_STATUS_CODE)); + if (*StatusCode == NULL) { + ret = NULL; + } else { + **StatusCode = HTTP_STATUS_200_OK; + } + } + + cleanupPayload(members); + return ret; + } + + if(json_is_array(payload->json)) + { + // + // The valid range for index is from 0 to the return value of json_array_size() minus 1 + // + value = json_array_get(payload->json, index); + } + else if(json_is_object(payload->json)) + { + value = json_object_get_by_index(payload->json, index); + } + + if(value == NULL) + { + return NULL; + } + + json_incref(value); + if(json_object_size(value) == 1) + { + odataId = json_object_get(value, "@odata.id"); + if(odataId != NULL) + { + uri = json_string_value(odataId); + json_decref(value); + value = getUriFromService(payload->service, uri, StatusCode); + if(value == NULL) + { + return NULL; + } + } + } + return createRedfishPayload(value, payload->service); +} + +redfishPayload* getPayloadForPath(redfishPayload* payload, redPathNode* redpath, EFI_HTTP_STATUS_CODE** StatusCode) +{ + redfishPayload* ret = NULL; + redfishPayload* tmp; + + if(!payload || !redpath || StatusCode == NULL) + { + return NULL; + } + + *StatusCode = NULL; + BOOLEAN FromServerFlag = FALSE; + + if(redpath->nodeName) + { + ret = getPayloadByNodeName(payload, redpath->nodeName, StatusCode); + if ((*StatusCode == NULL && ret == NULL) || + (*StatusCode != NULL && (**StatusCode < HTTP_STATUS_200_OK || **StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))) { + // + // Any error happen, return directly. + // + return ret; + } + } + else if(redpath->isIndex) + { + ASSERT (redpath->index >= 1); + ret = getPayloadByIndex(payload, redpath->index - 1, StatusCode); + if ((*StatusCode == NULL && ret == NULL) || + (*StatusCode != NULL && (**StatusCode < HTTP_STATUS_200_OK || **StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))) { + // + // Any error happen, return directly. + // + return ret; + } + } + else if(redpath->op) + { + ret = getOpResult(payload, redpath->propName, redpath->op, redpath->value, StatusCode); + if ((*StatusCode == NULL && ret == NULL) || + (*StatusCode != NULL && (**StatusCode < HTTP_STATUS_200_OK || **StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))) { + // + // Any error happen, return directly. + // + return ret; + } + } + else + { + return NULL; + } + + if(redpath->next == NULL || ret == NULL) + { + return ret; + } + else + { + if (*StatusCode != NULL) { + FreePool (*StatusCode); + *StatusCode = NULL; + FromServerFlag = TRUE; + } + + tmp = getPayloadForPath(ret, redpath->next, StatusCode); + if (*StatusCode == NULL && tmp != NULL && FromServerFlag) { + // + // In such a case, the Redfish resource is parsed from the input payload (ret) directly. + // Since the ret are retrived from server, we still return HTTP_STATUS_200_OK. + // + *StatusCode = AllocateZeroPool (sizeof (EFI_HTTP_STATUS_CODE)); + if (*StatusCode == NULL) { + tmp = NULL; + } else { + **StatusCode = HTTP_STATUS_200_OK; + } + } + + cleanupPayload(ret); + return tmp; + } +} + +redfishPayload* getPayloadForPathString(redfishPayload* payload, const char* string, EFI_HTTP_STATUS_CODE** StatusCode) +{ + redPathNode* redpath; + redfishPayload* ret; + + if(!string || StatusCode == NULL) + { + return NULL; + } + + *StatusCode = NULL; + + redpath = parseRedPath(string); + if(redpath == NULL) + { + return NULL; + } + ret = getPayloadForPath(payload, redpath, StatusCode); + cleanupRedPath(redpath); + return ret; +} + +redfishPayload* patchPayload(redfishPayload* target, redfishPayload* payload, EFI_HTTP_STATUS_CODE** StatusCode) +{ + json_t* json; + char* content; + char* uri; + + if(!target || !payload || StatusCode == NULL) + { + return NULL; + } + + *StatusCode = NULL; + + json = json_object_get(target->json, "@odata.id"); + if(json == NULL) + { + return NULL; + } + uri = strdup(json_string_value(json)); + + content = json_dumps(payload->json, 0); + json_decref(json); + + json = patchUriFromService(target->service, uri, content, StatusCode); + free(uri); + free(content); + if(json == NULL) + { + return NULL; + } + + return createRedfishPayload(json, target->service); +} + +redfishPayload* postContentToPayload(redfishPayload* target, const char* data, size_t dataSize, const char* contentType, EFI_HTTP_STATUS_CODE** StatusCode) +{ + json_t* json; + char* uri; + + if(!target || !data || StatusCode == NULL) + { + return NULL; + } + + *StatusCode = NULL; + + json = json_object_get(target->json, "@odata.id"); + if(json == NULL) + { + json = json_object_get(target->json, "target"); + if(json == NULL) + { + return NULL; + } + } + uri = strdup(json_string_value(json)); + json = postUriFromService(target->service, uri, data, dataSize, contentType, StatusCode); + free(uri); + if(json == NULL) + { + return NULL; + } + + return createRedfishPayload(json, target->service); +} + +redfishPayload* postPayload(redfishPayload* target, redfishPayload* payload, EFI_HTTP_STATUS_CODE** StatusCode) +{ + char* content; + redfishPayload* ret; + + if(!target || !payload || StatusCode == NULL) + { + return NULL; + } + + *StatusCode = NULL; + + if(!json_is_object(payload->json)) + { + return NULL; + } + content = payloadToString(payload, false); + ret = postContentToPayload(target, content, strlen(content), NULL, StatusCode); + free(content); + return ret; +} + +void cleanupPayload(redfishPayload* payload) +{ + if(!payload) + { + return; + } + json_decref(payload->json); + //Don't free payload->service, let the caller handle cleaning up the service + free(payload); +} + +static redfishPayload* getOpResult(redfishPayload* payload, const char* propName, const char* op, const char* value, EFI_HTTP_STATUS_CODE** StatusCode) +{ + const char* propStr; + json_t* stringProp; + bool ret = false; + redfishPayload* prop; + long long intVal, intPropVal; + json_type jsonType; + + if(isPayloadCollection(payload)) + { + return collectionEvalOp(payload, propName, op, value, StatusCode); + } + if(isPayloadArray(payload)) + { + return arrayEvalOp(payload, propName, op, value, StatusCode); + } + + prop = getPayloadByNodeName(payload, propName, StatusCode); + if ((*StatusCode == NULL && prop == NULL) || + (*StatusCode != NULL && (**StatusCode < HTTP_STATUS_200_OK || **StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))) { + return prop; + } + stringProp = prop->json; + jsonType = prop->json->type; + switch(jsonType) + { + case JSON_OBJECT: + stringProp = json_object_get(prop->json, propName); + case JSON_STRING: + if(strcmp(op, "=") == 0) + { + propStr = json_string_value(stringProp); + if(propStr == NULL) + { + cleanupPayload(prop); + return NULL; + } + ret = (strcmp(propStr, value) == 0); + } else if(strcmp(op, "~") == 0) + { + propStr = json_string_value(stringProp); + if(propStr == NULL) + { + cleanupPayload(prop); + return NULL; + } + ret = (strcasecmp(propStr, value) == 0); + } + break; + case JSON_TRUE: + if(strcmp(op, "=") == 0) + { + ret = (strcmp(value, "true") == 0); + } + break; + case JSON_FALSE: + if(strcmp(op, "=") == 0) + { + ret = (strcmp(value, "false") == 0); + } + break; + case JSON_INTEGER: + intPropVal = json_integer_value(prop->json); + intVal = strtoll(value, NULL, 0); + if(strcmp(op, "=") == 0) + { + ret = (intPropVal == intVal); + } + else if(strcmp(op, "<") == 0) + { + ret = (intPropVal < intVal); + } + else if(strcmp(op, ">") == 0) + { + ret = (intPropVal > intVal); + } + else if(strcmp(op, "<=") == 0) + { + ret = (intPropVal <= intVal); + } + else if(strcmp(op, ">=") == 0) + { + ret = (intPropVal >= intVal); + } + break; + default: + break; + } + cleanupPayload(prop); + if(ret) + { + return payload; + } + else + { + return NULL; + } +} + +static redfishPayload* collectionEvalOp(redfishPayload* payload, const char* propName, const char* op, const char* value, EFI_HTTP_STATUS_CODE** StatusCode) +{ + redfishPayload* ret; + redfishPayload* tmp; + redfishPayload* members; + redfishPayload** valid; + size_t validMax; + size_t validCount = 0; + size_t i; + + validMax = getCollectionSize(payload); + if(validMax == 0) + { + return NULL; + } + + valid = (redfishPayload**)calloc(validMax, sizeof(redfishPayload*)); + if(valid == NULL) + { + return NULL; + } + /*Technically getPayloadByIndex would do this, but this optimizes things*/ + members = getPayloadByNodeName(payload, "Members", StatusCode); + if ((*StatusCode == NULL && members == NULL) || + (*StatusCode != NULL && (**StatusCode < HTTP_STATUS_200_OK || **StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))) { + return members; + } + + for(i = 0; i < validMax; i++) + { + if (*StatusCode != NULL) { + FreePool (*StatusCode); + *StatusCode = NULL; + } + + tmp = getPayloadByIndex(members, i, StatusCode); + if ((*StatusCode == NULL && tmp == NULL) || + (*StatusCode != NULL && (**StatusCode < HTTP_STATUS_200_OK || **StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))) { + return tmp; + } + + if (*StatusCode != NULL) { + FreePool (*StatusCode); + *StatusCode = NULL; + } + + valid[validCount] = getOpResult(tmp, propName, op, value, StatusCode); + /* + if ((*StatusCode == NULL && valid[validCount] == NULL) || + (*StatusCode != NULL && (**StatusCode < HTTP_STATUS_200_OK || **StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))) { + return valid[validCount]; + } + */ + if(valid[validCount] != NULL) + { + validCount++; + } + else + { + cleanupPayload(tmp); + } + } + cleanupPayload(members); + if(validCount == 0) + { + free(valid); + return NULL; + } + if(validCount == 1) + { + ret = valid[0]; + free(valid); + return ret; + } + else + { + ret = createCollection(payload->service, validCount, valid); + free(valid); + return ret; + } +} + +static redfishPayload* arrayEvalOp(redfishPayload* payload, const char* propName, const char* op, const char* value, EFI_HTTP_STATUS_CODE** StatusCode) +{ + redfishPayload* ret; + redfishPayload* tmp; + redfishPayload** valid; + size_t validMax; + size_t validCount = 0; + size_t i; + + validMax = json_array_size(payload->json); + if(validMax == 0) + { + return NULL; + } + + valid = (redfishPayload**)calloc(validMax, sizeof(redfishPayload*)); + if(valid == NULL) + { + return NULL; + } + for(i = 0; i < validMax; i++) + { + if (*StatusCode != NULL) { + FreePool (*StatusCode); + *StatusCode = NULL; + } + + tmp = getPayloadByIndex(payload, i, StatusCode); + if ((*StatusCode == NULL && tmp == NULL) || + (*StatusCode != NULL && (**StatusCode < HTTP_STATUS_200_OK || **StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))) { + return tmp; + } + + if (*StatusCode != NULL) { + FreePool (*StatusCode); + *StatusCode = NULL; + } + + valid[validCount] = getOpResult(tmp, propName, op, value, StatusCode); + /* + if ((*StatusCode == NULL && valid[validCount] == NULL) || + (*StatusCode != NULL && (**StatusCode < HTTP_STATUS_200_OK || **StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT))) { + return valid[validCount]; + } + */ + + if(valid[validCount] != NULL) + { + validCount++; + } + else + { + cleanupPayload(tmp); + } + } + if(validCount == 0) + { + free(valid); + return NULL; + } + if(validCount == 1) + { + ret = valid[0]; + free(valid); + return ret; + } + else + { + ret = createCollection(payload->service, validCount, valid); + free(valid); + return ret; + } +} + +static redfishPayload* createCollection(redfishService* service, size_t count, redfishPayload** payloads) +{ + redfishPayload* ret; + json_t* collectionJson = json_object(); + json_t* jcount = json_integer((json_int_t)count); + json_t* members = json_array(); + size_t i; + + if(!collectionJson) + { + return NULL; + } + if(!members) + { + json_decref(collectionJson); + return NULL; + } + json_object_set(collectionJson, "Members@odata.count", jcount); + json_decref(jcount); + for(i = 0; i < count; i++) + { + json_array_append(members, payloads[i]->json); + cleanupPayload(payloads[i]); + } + json_object_set(collectionJson, "Members", members); + json_decref(members); + + ret = createRedfishPayload(collectionJson, service); + return ret; +} + +static json_t* json_object_get_by_index(json_t* json, size_t index) +{ + void* iter; + size_t i; + + iter = json_object_iter(json); + for(i = 0; i < index; i++) + { + iter = json_object_iter_next(json, iter); + if(iter == NULL) break; + } + if(iter == NULL) + { + return NULL; + } + return json_object_iter_value(iter); +} +/* vim: set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/redpath.c b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/redpath.c new file mode 100644 index 00000000000..28291426153 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/redpath.c @@ -0,0 +1,192 @@ +/** @file + This file is cloned from DMTF libredfish library tag v1.0.0 and maintained + by EDKII. + +//---------------------------------------------------------------------------- +// Copyright Notice: +// Copyright 2017 Distributed Management Task Force, Inc. All rights reserved. +// License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libredfish/LICENSE.md +//---------------------------------------------------------------------------- + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include + +static char* getVersion(const char* path, char** end); +static void parseNode(const char* path, redPathNode* node, redPathNode** end); + +static char* getStringTill(const char* string, const char* terminator, char** retEnd); + +redPathNode* parseRedPath(const char* path) +{ + redPathNode* node; + redPathNode* endNode; + char* curPath; + char* end; + + if(!path || strlen(path) == 0) + { + return NULL; + } + + node = (redPathNode*)calloc(1, sizeof(redPathNode)); + if(!node) + { + return NULL; + } + if(path[0] == '/') + { + node->isRoot = true; + if(path[1] == 'v') + { + node->version = getVersion(path+1, &curPath); + if(curPath == NULL) + { + return node; + } + if(curPath[0] == '/') + { + curPath++; + } + node->next = parseRedPath(curPath); + } + else + { + node->next = parseRedPath(path+1); + } + return node; + } + node->isRoot = false; + curPath = getStringTill(path, "/", &end); + endNode = node; + parseNode(curPath, node, &endNode); + free(curPath); + if(end != NULL) + { + endNode->next = parseRedPath(end+1); + } + return node; +} + +void cleanupRedPath(redPathNode* node) +{ + if(!node) + { + return; + } + cleanupRedPath(node->next); + node->next = NULL; + if(node->version) + { + free(node->version); + } + if(node->nodeName) + { + free(node->nodeName); + } + if(node->op) + { + free(node->op); + } + if(node->propName) + { + free(node->propName); + } + if(node->value) + { + free(node->value); + } + free(node); +} + +static char* getVersion(const char* path, char** end) +{ + return getStringTill(path, "/", end); +} + +static void parseNode(const char* path, redPathNode* node, redPathNode** end) +{ + char* indexStart; + char* index; + char* indexEnd; + char* nodeName = getStringTill(path, "[", &indexStart); + size_t tmpIndex; + char* opChars; + + node->nodeName = nodeName; + if(indexStart == NULL) + { + *end = node; + return; + } + node->next = (redPathNode*)calloc(1, sizeof(redPathNode)); + if(!node->next) + { + return; + } + //Skip past [ + indexStart++; + *end = node->next; + index = getStringTill(indexStart, "]", NULL); + tmpIndex = (size_t)strtoull(index, &indexEnd, 0); + if(indexEnd != index) + { + free(index); + node->next->index = tmpIndex; + node->next->isIndex = true; + return; + } + opChars = strpbrk(index, "<>=~"); + if(opChars == NULL) + { + //TODO handle last() and position() + node->next->op = strdup("exists"); + node->next->propName = index; + return; + } + node->next->propName = (char*)malloc((opChars - index)+1); + memcpy(node->next->propName, index, (opChars - index)); + node->next->propName[(opChars - index)] = 0; + + tmpIndex = 1; + while(1) + { + if(opChars[tmpIndex] == '=' || opChars[tmpIndex] == '<' || opChars[tmpIndex] == '>' || opChars[tmpIndex] == '~') + { + tmpIndex++; + continue; + } + break; + } + + node->next->op = (char*)malloc(tmpIndex+1); + memcpy(node->next->op, opChars, tmpIndex); + node->next->op[tmpIndex] = 0; + + node->next->value = strdup(opChars+tmpIndex); + free(index); +} + +static char* getStringTill(const char* string, const char* terminator, char** retEnd) +{ + char* ret; + char* end; + end = strstr((char*)string, terminator); + if(retEnd) + { + *retEnd = end; + } + if(end == NULL) + { + //No terminator + return strdup(string); + } + ret = (char*)malloc((end-string)+1); + memcpy(ret, string, (end-string)); + ret[(end-string)] = 0; + return ret; +} diff --git a/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/service.c b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/service.c new file mode 100644 index 00000000000..7139a2e2e9c --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/PrivateLibrary/RedfishLib/edk2libredfish/src/service.c @@ -0,0 +1,1396 @@ +/** @file + This file is cloned from DMTF libredfish library tag v1.0.0 and maintained + by EDKII. + +//---------------------------------------------------------------------------- +// Copyright Notice: +// Copyright 2017 Distributed Management Task Force, Inc. All rights reserved. +// License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libredfish/LICENSE.md +//---------------------------------------------------------------------------- + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +static int initRest(redfishService* service, void * restProtocol); +static redfishService* createServiceEnumeratorNoAuth(const char* host, const char* rootUri, bool enumerate, unsigned int flags, void * restProtocol); +static redfishService* createServiceEnumeratorBasicAuth(const char* host, const char* rootUri, const char* username, const char* password, unsigned int flags, void * restProtocol); +static redfishService* createServiceEnumeratorSessionAuth(const char* host, const char* rootUri, const char* username, const char* password, unsigned int flags, void * restProtocol); +static char* makeUrlForService(redfishService* service, const char* uri); +static json_t* getVersions(redfishService* service, const char* rootUri); +static void addStringToJsonObject(json_t* object, const char* key, const char* value); + +CHAR16* +C8ToC16 (CHAR8 *AsciiStr) +{ + CHAR16 *Str; + UINTN BufLen; + + BufLen = (AsciiStrLen (AsciiStr) + 1) * 2; + Str = AllocatePool (BufLen); + ASSERT (Str != NULL); + + AsciiStrToUnicodeStrS (AsciiStr, Str, AsciiStrLen (AsciiStr) + 1); + + return Str; +} + +VOID +RestConfigFreeHttpRequestData ( + IN EFI_HTTP_REQUEST_DATA *RequestData + ) +{ + if (RequestData == NULL) { + return ; + } + + if (RequestData->Url != NULL) { + FreePool (RequestData->Url); + } + + FreePool (RequestData); +} + +VOID +RestConfigFreeHttpMessage ( + IN EFI_HTTP_MESSAGE *Message, + IN BOOLEAN IsRequest + ) +{ + if (Message == NULL) { + return ; + } + + if (IsRequest) { + RestConfigFreeHttpRequestData (Message->Data.Request); + Message->Data.Request = NULL; + } else { + if (Message->Data.Response != NULL) { + FreePool (Message->Data.Response); + Message->Data.Response = NULL; + } + } + + if (Message->Headers != NULL) { + FreePool (Message->Headers); + Message->Headers = NULL; + } + if (Message->Body != NULL) { + FreePool (Message->Body); + Message->Body = NULL; + } +} + +/** + Converts the Unicode string to ASCII string to a new allocated buffer. + + @param[in] String Unicode string to be converted. + + @return Buffer points to ASCII string, or NULL if error happens. + +**/ + +CHAR8 * +UnicodeStrDupToAsciiStr ( + CONST CHAR16 *String + ) +{ + CHAR8 *AsciiStr; + UINTN BufLen; + EFI_STATUS Status; + + BufLen = StrLen (String) + 1; + AsciiStr = AllocatePool (BufLen); + if (AsciiStr == NULL) { + return NULL; + } + + Status = UnicodeStrToAsciiStrS (String, AsciiStr, BufLen); + if (EFI_ERROR (Status)) { + return NULL; + } + + return AsciiStr; +} +/** + This function encodes the content. + + @param[in] ContentEncodedValue HTTP conent encoded value. + @param[in] OriginalContent Original content. + @param[out] EncodedContent Pointer to receive encoded content. + @param[out] EncodedContentLength Length of encoded content. + + @retval EFI_SUCCESS Content encoded successfully. + @retval EFI_UNSUPPORTED No source encoding funciton, + @retval EFI_INVALID_PARAMETER One of the given parameter is invalid. + +**/ +EFI_STATUS +EncodeRequestContent ( + IN CHAR8 *ContentEncodedValue, + IN CHAR8 *OriginalContent, + OUT VOID **EncodedContent, + OUT UINTN *EncodedContentLength +) +{ + EFI_STATUS Status; + VOID *EncodedPointer; + UINTN EncodedLength; + + if (OriginalContent == NULL || EncodedContent == NULL || EncodedContentLength == NULL) { + return EFI_INVALID_PARAMETER; + } + Status = RedfishContentEncode ( + ContentEncodedValue, + OriginalContent, + AsciiStrLen (OriginalContent), + &EncodedPointer, + &EncodedLength + ); + if (Status == EFI_SUCCESS) { + *EncodedContent = EncodedPointer; + *EncodedContentLength = EncodedLength; + return EFI_SUCCESS; + } + return Status; +} + +/** + This function decodes the content. The Memory block pointed by + ContentPointer would be freed and replaced with the cooked Redfish + payload. + + @param[in] ContentEncodedValue HTTP conent encoded value. + @param[in, out] ContentPointer Pointer to encoded content. + Pointer of decoded content when out. + @param[in, out] ContentLength Pointer to the length of encoded content. + Length of decoded content when out. + + @retval EFI_SUCCESS Functinos found. + @retval EFI_UNSUPPORTED No functions found. + @retval EFI_INVALID_PARAMETER One of the given parameter is invalid. + +**/ +EFI_STATUS +DecodeResponseContent ( + IN CHAR8 *ContentEncodedValue, + IN OUT VOID **ContentPointer, + IN OUT UINTN *ContentLength +) +{ + EFI_STATUS Status; + VOID *DecodedPointer; + UINTN DecodedLength; + + if (ContentEncodedValue == NULL) { + return EFI_INVALID_PARAMETER; + } + Status = RedfishContentDecode ( + ContentEncodedValue, + *ContentPointer, + *ContentLength, + &DecodedPointer, + &DecodedLength + ); + if (Status == EFI_SUCCESS) { + FreePool (*ContentPointer); + *ContentPointer = DecodedPointer; + *ContentLength = DecodedLength; + } + return Status; +} + +/** + Create a HTTP URL string for specific Redfish resource. + + This function build a URL string from the Redfish Host interface record and caller specified + relative path of the resource. + + Callers are responsible for freeing the returned string storage pointed by HttpUrl. + + @param[in] RedfishData Redfish network host interface record. + @param[in] RelativePath Relative path of a resource. + @param[out] HttpUrl The pointer to store the returned URL string. + + @retval EFI_SUCCESS Build the URL string successfully. + @retval EFI_INVALID_PARAMETER RedfishData or HttpUrl is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough memory resources. + +**/ +EFI_STATUS +RedfishBuildUrl ( + IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo, + IN CHAR16 *RelativePath, OPTIONAL + OUT CHAR16 **HttpUrl + ) +{ + CHAR16 *Url; + CHAR16 *UrlHead; + UINTN UrlLength; + UINTN PathLen; + + if ((RedfishConfigServiceInfo == NULL) || (HttpUrl == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // RFC2616: http_URL = "http(s):" "//" host [ ":" port ] [ abs_path [ "?" query ]] + // + if (RelativePath == NULL) { + PathLen = 0; + } else { + PathLen = StrLen (RelativePath); + } + UrlLength = StrLen (HTTPS_FLAG) + StrLen (REDFISH_FIRST_URL) + 1 + StrLen(RedfishConfigServiceInfo->RedfishServiceLocation) + PathLen; + Url = AllocateZeroPool (UrlLength * sizeof (CHAR16)); + if (Url == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + UrlHead = Url; + // + // Copy "http://" or "https://" according RedfishServiceIpPort. + // + if (!RedfishConfigServiceInfo->RedfishServiceUseHttps) { + StrCpyS (Url, StrLen (HTTPS_FLAG) + 1, HTTP_FLAG); + Url = Url + StrLen (HTTP_FLAG); + } else { + StrCpyS (Url, StrLen (HTTPS_FLAG) + 1, HTTPS_FLAG); + Url = Url + StrLen (HTTPS_FLAG); + } + + StrCpyS (Url, StrLen (RedfishConfigServiceInfo->RedfishServiceLocation) + 1, RedfishConfigServiceInfo->RedfishServiceLocation); + Url = Url + StrLen (RedfishConfigServiceInfo->RedfishServiceLocation); + + // + // Copy abs_path + // + if (RelativePath != NULL && PathLen != 0 ) { + StrnCpyS (Url, UrlLength, RelativePath, PathLen); + } + *HttpUrl = UrlHead; + return EFI_SUCCESS; +} + +redfishService* createServiceEnumerator(REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo, const char* rootUri, enumeratorAuthentication* auth, unsigned int flags) +{ + EFI_STATUS Status; + CHAR16 *HttpUrl; + CHAR8 *AsciiHost; + EFI_REST_EX_PROTOCOL *RestEx; + redfishService *ret; + + HttpUrl = NULL; + AsciiHost = NULL; + RestEx = NULL; + ret = NULL; + + if (RedfishConfigServiceInfo->RedfishServiceRestExHandle == NULL) { + goto ON_EXIT; + } + Status = RedfishBuildUrl(RedfishConfigServiceInfo, NULL, &HttpUrl); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + ASSERT (HttpUrl != NULL); + + AsciiHost = UnicodeStrDupToAsciiStr (HttpUrl); + if (AsciiHost == NULL) { + goto ON_EXIT; + } + + Status = gBS->HandleProtocol ( + RedfishConfigServiceInfo->RedfishServiceRestExHandle, + &gEfiRestExProtocolGuid, + (VOID **)&RestEx + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + if(auth == NULL) { + ret = createServiceEnumeratorNoAuth(AsciiHost, rootUri, true, flags, RestEx); + } else if(auth->authType == REDFISH_AUTH_BASIC) { + ret = createServiceEnumeratorBasicAuth(AsciiHost, rootUri, auth->authCodes.userPass.username, auth->authCodes.userPass.password, flags, RestEx); + } else if(auth->authType == REDFISH_AUTH_SESSION) { + ret = createServiceEnumeratorSessionAuth(AsciiHost, rootUri, auth->authCodes.userPass.username, auth->authCodes.userPass.password, flags, RestEx); + } else { + goto ON_EXIT; + } + + ret->RestEx = RestEx; +ON_EXIT: + if (HttpUrl != NULL) { + FreePool (HttpUrl); + } + + if (AsciiHost != NULL) { + FreePool (AsciiHost); + } + + return ret; +} + +json_t* getUriFromService(redfishService* service, const char* uri, EFI_HTTP_STATUS_CODE** StatusCode) +{ + char* url; + json_t* ret; + HTTP_IO_HEADER *HttpIoHeader = NULL; + EFI_STATUS Status; + EFI_HTTP_REQUEST_DATA *RequestData = NULL; + EFI_HTTP_MESSAGE *RequestMsg = NULL; + EFI_HTTP_MESSAGE ResponseMsg; + EFI_HTTP_HEADER *ContentEncodedHeader; + + if(service == NULL || uri == NULL || StatusCode == NULL) + { + return NULL; + } + + *StatusCode = NULL; + + url = makeUrlForService(service, uri); + if(!url) + { + return NULL; + } + + DEBUG((DEBUG_INFO, "libredfish: getUriFromService(): %a\n", url)); + + // + // Step 1: Create HTTP request message with 4 headers: + // + HttpIoHeader = HttpIoCreateHeader ((service->sessionToken || service->basicAuthStr) ? 6 : 5); + if (HttpIoHeader == NULL) { + ret = NULL; + goto ON_EXIT; + } + + if(service->sessionToken) + { + Status = HttpIoSetHeader (HttpIoHeader, "X-Auth-Token", service->sessionToken); + ASSERT_EFI_ERROR (Status); + } else if (service->basicAuthStr) { + Status = HttpIoSetHeader (HttpIoHeader, "Authorization", service->basicAuthStr); + ASSERT_EFI_ERROR (Status); + } + + Status = HttpIoSetHeader (HttpIoHeader, "Host", service->HostHeaderValue); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "OData-Version", "4.0"); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "Accept", "application/json"); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "User-Agent", "libredfish"); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "Connection", "Keep-Alive"); + ASSERT_EFI_ERROR (Status); + + // + // Step 2: build the rest of HTTP request info. + // + RequestData = AllocateZeroPool (sizeof (EFI_HTTP_REQUEST_DATA)); + if (RequestData == NULL) { + ret = NULL; + goto ON_EXIT; + } + + RequestData->Method = HttpMethodGet; + RequestData->Url = C8ToC16 (url); + + // + // Step 3: fill in EFI_HTTP_MESSAGE + // + RequestMsg = AllocateZeroPool (sizeof (EFI_HTTP_MESSAGE)); + if (RequestMsg == NULL) { + ret = NULL; + goto ON_EXIT; + } + + RequestMsg->Data.Request = RequestData; + RequestMsg->HeaderCount = HttpIoHeader->HeaderCount; + RequestMsg->Headers = HttpIoHeader->Headers; + + ZeroMem (&ResponseMsg, sizeof (ResponseMsg)); + + // + // Step 4: call RESTEx to get response from REST service. + // + Status = service->RestEx->SendReceive (service->RestEx, RequestMsg, &ResponseMsg); + if (EFI_ERROR (Status)) { + ret = NULL; + goto ON_EXIT; + } + + // + // Step 5: Return the HTTP StatusCode and Body message. + // + if (ResponseMsg.Data.Response != NULL) { + *StatusCode = AllocateZeroPool (sizeof (EFI_HTTP_STATUS_CODE)); + if (*StatusCode == NULL) { + ret = NULL; + goto ON_EXIT; + } + + // + // The caller shall take the responsibility to free the buffer. + // + **StatusCode = ResponseMsg.Data.Response->StatusCode; + } + + if (ResponseMsg.BodyLength != 0 && ResponseMsg.Body != NULL) { + // + // Check if data is encoded. + // + ContentEncodedHeader = HttpFindHeader (ResponseMsg.HeaderCount, ResponseMsg.Headers, HTTP_HEADER_CONTENT_ENCODING); + if (ContentEncodedHeader != NULL) { + // + // The content is encoded. + // + Status = DecodeResponseContent (ContentEncodedHeader->FieldValue, &ResponseMsg.Body, &ResponseMsg.BodyLength); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to decompress the response content %r\n.", __FUNCTION__, Status)); + ret = NULL; + goto ON_EXIT; + } + } + ret = json_loadb (ResponseMsg.Body, ResponseMsg.BodyLength, 0, NULL); + } else { + // + // There is no message body returned from server. + // + ret = NULL; + } + +ON_EXIT: + if (url != NULL) { + free (url); + } + + if (HttpIoHeader != NULL) { + HttpIoFreeHeader (HttpIoHeader); + } + + if (RequestData != NULL) { + RestConfigFreeHttpRequestData (RequestData); + } + + if (RequestMsg != NULL) { + FreePool (RequestMsg); + } + + RestConfigFreeHttpMessage (&ResponseMsg, FALSE); + + return ret; +} + +json_t* patchUriFromService(redfishService* service, const char* uri, const char* content, EFI_HTTP_STATUS_CODE** StatusCode) +{ + char* url; + json_t* ret; + HTTP_IO_HEADER *HttpIoHeader = NULL; + EFI_STATUS Status; + EFI_HTTP_REQUEST_DATA *RequestData = NULL; + EFI_HTTP_MESSAGE *RequestMsg = NULL; + EFI_HTTP_MESSAGE ResponseMsg; + CHAR8 ContentLengthStr[80]; + CHAR8 *EncodedContent; + UINTN EncodedContentLen; + + if(service == NULL || uri == NULL || content == NULL || StatusCode == NULL) + { + return NULL; + } + + *StatusCode = NULL; + + url = makeUrlForService(service, uri); + if(!url) + { + return NULL; + } + + DEBUG((DEBUG_INFO, "libredfish: patchUriFromService(): %a\n", url)); + + // + // Step 1: Create HTTP request message with 4 headers: + // + HttpIoHeader = HttpIoCreateHeader ((service->sessionToken || service->basicAuthStr) ? 9 : 8); + if (HttpIoHeader == NULL) { + ret = NULL; + goto ON_EXIT; + } + + if(service->sessionToken) + { + Status = HttpIoSetHeader (HttpIoHeader, "X-Auth-Token", service->sessionToken); + ASSERT_EFI_ERROR (Status); + } else if (service->basicAuthStr) { + Status = HttpIoSetHeader (HttpIoHeader, "Authorization", service->basicAuthStr); + ASSERT_EFI_ERROR (Status); + } + + Status = HttpIoSetHeader (HttpIoHeader, "Host", service->HostHeaderValue); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "Content-Type", "application/json"); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "Accept", "application/json"); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "User-Agent", "libredfish"); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "Connection", "Keep-Alive"); + ASSERT_EFI_ERROR (Status); + + AsciiSPrint( + ContentLengthStr, + sizeof (ContentLengthStr), + "%lu", + (UINT64) strlen(content) + ); + Status = HttpIoSetHeader (HttpIoHeader, "Content-Length", ContentLengthStr); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "OData-Version", "4.0"); + ASSERT_EFI_ERROR (Status); + + // + // Step 2: build the rest of HTTP request info. + // + RequestData = AllocateZeroPool (sizeof (EFI_HTTP_REQUEST_DATA)); + if (RequestData == NULL) { + ret = NULL; + goto ON_EXIT; + } + + RequestData->Method = HttpMethodPatch; + RequestData->Url = C8ToC16 (url); + + // + // Step 3: fill in EFI_HTTP_MESSAGE + // + RequestMsg = AllocateZeroPool (sizeof (EFI_HTTP_MESSAGE)); + if (RequestMsg == NULL) { + ret = NULL; + goto ON_EXIT; + } + + EncodedContent = (CHAR8 *)content; + EncodedContentLen = strlen(content); + // + // We currently only support gzip Content-Encoding. + // + Status = EncodeRequestContent ((CHAR8 *)HTTP_CONTENT_ENCODING_GZIP, (CHAR8 *)content, (VOID **)&EncodedContent, &EncodedContentLen); + if (Status == EFI_INVALID_PARAMETER) { + DEBUG((DEBUG_ERROR, "%a: Error to encode content.\n", __FUNCTION__)); + ret = NULL; + goto ON_EXIT; + } else if (Status == EFI_UNSUPPORTED) { + DEBUG((DEBUG_INFO, "No content coding for %a! Use raw data instead.\n", HTTP_CONTENT_ENCODING_GZIP)); + Status = HttpIoSetHeader (HttpIoHeader, "Content-Encoding", HTTP_CONTENT_ENCODING_IDENTITY); + ASSERT_EFI_ERROR (Status); + } else { + Status = HttpIoSetHeader (HttpIoHeader, "Content-Encoding", HTTP_CONTENT_ENCODING_GZIP); + ASSERT_EFI_ERROR (Status); + } + + RequestMsg->Data.Request = RequestData; + RequestMsg->HeaderCount = HttpIoHeader->HeaderCount; + RequestMsg->Headers = HttpIoHeader->Headers; + RequestMsg->BodyLength = EncodedContentLen; + RequestMsg->Body = (VOID*) EncodedContent; + + ZeroMem (&ResponseMsg, sizeof (ResponseMsg)); + + // + // Step 4: call RESTEx to get response from REST service. + // + Status = service->RestEx->SendReceive (service->RestEx, RequestMsg, &ResponseMsg); + if (EFI_ERROR (Status)) { + ret = NULL; + goto ON_EXIT; + } + + // + // Step 5: Return the HTTP StatusCode and Body message. + // + if (ResponseMsg.Data.Response != NULL) { + *StatusCode = AllocateZeroPool (sizeof (EFI_HTTP_STATUS_CODE)); + if (*StatusCode == NULL) { + ret = NULL; + goto ON_EXIT; + } + + // + // The caller shall take the responsibility to free the buffer. + // + **StatusCode = ResponseMsg.Data.Response->StatusCode; + } + + if (EncodedContent != content) { + FreePool (EncodedContent); + } + + + if (ResponseMsg.BodyLength != 0 && ResponseMsg.Body != NULL) { + ret = json_loadb (ResponseMsg.Body, ResponseMsg.BodyLength, 0, NULL); + } else { + // + // There is no message body returned from server. + // + ret = NULL; + } + +ON_EXIT: + if (url != NULL) { + free (url); + } + + if (HttpIoHeader != NULL) { + HttpIoFreeHeader (HttpIoHeader); + } + + if (RequestData != NULL) { + RestConfigFreeHttpRequestData (RequestData); + } + + if (RequestMsg != NULL) { + FreePool (RequestMsg); + } + + RestConfigFreeHttpMessage (&ResponseMsg, FALSE); + + return ret; +} + +json_t* postUriFromService(redfishService* service, const char* uri, const char* content, size_t contentLength, const char* contentType, EFI_HTTP_STATUS_CODE** StatusCode) +{ + char* url = NULL; + json_t* ret; + HTTP_IO_HEADER *HttpIoHeader = NULL; + EFI_STATUS Status; + EFI_HTTP_REQUEST_DATA *RequestData = NULL; + EFI_HTTP_MESSAGE *RequestMsg = NULL; + EFI_HTTP_MESSAGE ResponseMsg; + CHAR8 ContentLengthStr[80]; + EFI_HTTP_HEADER *HttpHeader = NULL; + + ret = NULL; + + if(service == NULL || uri == NULL || content == NULL || StatusCode == NULL) + { + return NULL; + } + + *StatusCode = NULL; + + url = makeUrlForService(service, uri); + if(!url) + { + return NULL; + } + + DEBUG((DEBUG_INFO, "libredfish: postUriFromService(): %a\n", url)); + + if(contentLength == 0) + { + contentLength = strlen(content); + } + + // + // Step 1: Create HTTP request message with 4 headers: + // + HttpIoHeader = HttpIoCreateHeader ((service->sessionToken || service->basicAuthStr) ? 8 : 7); + if (HttpIoHeader == NULL) { + goto ON_EXIT; + } + + if(service->sessionToken) + { + Status = HttpIoSetHeader (HttpIoHeader, "X-Auth-Token", service->sessionToken); + ASSERT_EFI_ERROR (Status); + } else if (service->basicAuthStr) { + Status = HttpIoSetHeader (HttpIoHeader, "Authorization", service->basicAuthStr); + ASSERT_EFI_ERROR (Status); + } + + if(contentType == NULL) { + Status = HttpIoSetHeader (HttpIoHeader, "Content-Type", "application/json"); + ASSERT_EFI_ERROR (Status); + } else { + Status = HttpIoSetHeader (HttpIoHeader, "Content-Type", (CHAR8 *) contentType); + ASSERT_EFI_ERROR (Status); + } + Status = HttpIoSetHeader (HttpIoHeader, "Host", service->HostHeaderValue); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "Accept", "application/json"); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "User-Agent", "libredfish"); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "Connection", "Keep-Alive"); + ASSERT_EFI_ERROR (Status); + AsciiSPrint( + ContentLengthStr, + sizeof (ContentLengthStr), + "%lu", + (UINT64) contentLength + ); + Status = HttpIoSetHeader (HttpIoHeader, "Content-Length", ContentLengthStr); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "OData-Version", "4.0"); + ASSERT_EFI_ERROR (Status); + + // + // Step 2: build the rest of HTTP request info. + // + RequestData = AllocateZeroPool (sizeof (EFI_HTTP_REQUEST_DATA)); + if (RequestData == NULL) { + goto ON_EXIT; + } + + RequestData->Method = HttpMethodPost; + RequestData->Url = C8ToC16 (url); + + // + // Step 3: fill in EFI_HTTP_MESSAGE + // + RequestMsg = AllocateZeroPool (sizeof (EFI_HTTP_MESSAGE)); + if (RequestMsg == NULL) { + goto ON_EXIT; + } + + RequestMsg->Data.Request = RequestData; + RequestMsg->HeaderCount = HttpIoHeader->HeaderCount; + RequestMsg->Headers = HttpIoHeader->Headers; + RequestMsg->BodyLength = contentLength; + RequestMsg->Body = (VOID*) content; + + ZeroMem (&ResponseMsg, sizeof (ResponseMsg)); + + // + // Step 4: call RESTEx to get response from REST service. + // + Status = service->RestEx->SendReceive (service->RestEx, RequestMsg, &ResponseMsg); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + // + // Step 5: Return the HTTP StatusCode and Body message. + // + if (ResponseMsg.Data.Response != NULL) { + *StatusCode = AllocateZeroPool (sizeof (EFI_HTTP_STATUS_CODE)); + if (*StatusCode == NULL) { + goto ON_EXIT; + } + + // + // The caller shall take the responsibility to free the buffer. + // + **StatusCode = ResponseMsg.Data.Response->StatusCode; + } + + if (ResponseMsg.BodyLength != 0 && ResponseMsg.Body != NULL) { + ret = json_loadb (ResponseMsg.Body, ResponseMsg.BodyLength, 0, NULL); + } + + // + // Step 6: Parsing the HttpHeader to retrive the X-Auth-Token if the HTTP StatusCode is correct. + // + if (ResponseMsg.Data.Response->StatusCode == HTTP_STATUS_200_OK || + ResponseMsg.Data.Response->StatusCode == HTTP_STATUS_204_NO_CONTENT) { + HttpHeader = HttpFindHeader (ResponseMsg.HeaderCount, ResponseMsg.Headers, "X-Auth-Token"); + if (HttpHeader != NULL) { + if(service->sessionToken) + { + free(service->sessionToken); + } + service->sessionToken = AllocateCopyPool (AsciiStrSize (HttpHeader->FieldValue), HttpHeader->FieldValue); + } + + /* + // + // Below opeation seems to be unnecessary. + // Besides, the FieldValue for the Location is the full HTTP URI (Http://0.0.0.0:5000/XXX), so we can't use it as the + // parameter of getUriFromService () directly. + // + HttpHeader = HttpFindHeader (ResponseMsg.HeaderCount, ResponseMsg.Headers, "Location"); + if (HttpHeader != NULL) { + ret = getUriFromService(service, HttpHeader->FieldValue); + goto ON_EXIT; + } + */ + } + +ON_EXIT: + if (url != NULL) { + free (url); + } + + if (HttpIoHeader != NULL) { + HttpIoFreeHeader (HttpIoHeader); + } + + if (RequestData != NULL) { + RestConfigFreeHttpRequestData (RequestData); + } + + if (RequestMsg != NULL) { + FreePool (RequestMsg); + } + + RestConfigFreeHttpMessage (&ResponseMsg, FALSE); + + return ret; +} + +json_t* deleteUriFromService(redfishService* service, const char* uri, EFI_HTTP_STATUS_CODE** StatusCode) +{ + char* url; + json_t* ret; + HTTP_IO_HEADER *HttpIoHeader = NULL; + EFI_STATUS Status; + EFI_HTTP_REQUEST_DATA *RequestData = NULL; + EFI_HTTP_MESSAGE *RequestMsg = NULL; + EFI_HTTP_MESSAGE ResponseMsg; + + ret = NULL; + + if(service == NULL || uri == NULL || StatusCode == NULL) + { + return NULL; + } + + *StatusCode = NULL; + + url = makeUrlForService(service, uri); + if(!url) + { + return NULL; + } + + DEBUG((DEBUG_INFO, "libredfish: deleteUriFromService(): %a\n", url)); + + // + // Step 1: Create HTTP request message with 4 headers: + // + HttpIoHeader = HttpIoCreateHeader ((service->sessionToken || service->basicAuthStr) ? 5 : 4); + if (HttpIoHeader == NULL) { + ret = NULL; + goto ON_EXIT; + } + + if(service->sessionToken) + { + Status = HttpIoSetHeader (HttpIoHeader, "X-Auth-Token", service->sessionToken); + ASSERT_EFI_ERROR (Status); + } else if (service->basicAuthStr) { + Status = HttpIoSetHeader (HttpIoHeader, "Authorization", service->basicAuthStr); + ASSERT_EFI_ERROR (Status); + } + Status = HttpIoSetHeader (HttpIoHeader, "Host", service->HostHeaderValue); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "User-Agent", "libredfish"); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "OData-Version", "4.0"); + ASSERT_EFI_ERROR (Status); + Status = HttpIoSetHeader (HttpIoHeader, "Connection", "Keep-Alive"); + ASSERT_EFI_ERROR (Status); + + // + // Step 2: build the rest of HTTP request info. + // + RequestData = AllocateZeroPool (sizeof (EFI_HTTP_REQUEST_DATA)); + if (RequestData == NULL) { + ret = NULL; + goto ON_EXIT; + } + + RequestData->Method = HttpMethodDelete; + RequestData->Url = C8ToC16 (url); + + // + // Step 3: fill in EFI_HTTP_MESSAGE + // + RequestMsg = AllocateZeroPool (sizeof (EFI_HTTP_MESSAGE)); + if (RequestMsg == NULL) { + ret = NULL; + goto ON_EXIT; + } + + RequestMsg->Data.Request = RequestData; + RequestMsg->HeaderCount = HttpIoHeader->HeaderCount; + RequestMsg->Headers = HttpIoHeader->Headers; + + ZeroMem (&ResponseMsg, sizeof (ResponseMsg)); + + // + // Step 4: call RESTEx to get response from REST service. + // + Status = service->RestEx->SendReceive (service->RestEx, RequestMsg, &ResponseMsg); + if (EFI_ERROR (Status)) { + ret = NULL; + goto ON_EXIT; + } + + // + // Step 5: Return the HTTP StatusCode and Body message. + // + if (ResponseMsg.Data.Response != NULL) { + *StatusCode = AllocateZeroPool (sizeof (EFI_HTTP_STATUS_CODE)); + if (*StatusCode == NULL) { + ret = NULL; + goto ON_EXIT; + } + + // + // The caller shall take the responsibility to free the buffer. + // + **StatusCode = ResponseMsg.Data.Response->StatusCode; + } + + if (ResponseMsg.BodyLength != 0 && ResponseMsg.Body != NULL) { + ret = json_loadb (ResponseMsg.Body, ResponseMsg.BodyLength, 0, NULL); + } + +ON_EXIT: + if (url != NULL) { + free (url); + } + + if (HttpIoHeader != NULL) { + HttpIoFreeHeader (HttpIoHeader); + } + + if (RequestData != NULL) { + RestConfigFreeHttpRequestData (RequestData); + } + + if (RequestMsg != NULL) { + FreePool (RequestMsg); + } + + RestConfigFreeHttpMessage (&ResponseMsg, FALSE); + + return ret; +} + +redfishPayload* getRedfishServiceRoot(redfishService* service, const char* version, EFI_HTTP_STATUS_CODE** StatusCode) +{ + json_t* value; + json_t* versionNode; + const char* verUrl; + + if(version == NULL) + { + versionNode = json_object_get(service->versions, "v1"); + } + else + { + versionNode = json_object_get(service->versions, version); + } + if(versionNode == NULL) + { + return NULL; + } + verUrl = json_string_value(versionNode); + if(verUrl == NULL) + { + return NULL; + } + value = getUriFromService(service, verUrl, StatusCode); + if(value == NULL) + { + if((service->flags & REDFISH_FLAG_SERVICE_NO_VERSION_DOC) == 0) + { + json_decref(versionNode); + } + return NULL; + } + return createRedfishPayload(value, service); +} + +redfishPayload* getPayloadByPath(redfishService* service, const char* path, EFI_HTTP_STATUS_CODE** StatusCode) +{ + redPathNode* redpath; + redfishPayload* root; + redfishPayload* ret; + + if(!service || !path || StatusCode == NULL) + { + return NULL; + } + + *StatusCode = NULL; + + redpath = parseRedPath(path); + if(!redpath) + { + return NULL; + } + if(!redpath->isRoot) + { + cleanupRedPath(redpath); + return NULL; + } + root = getRedfishServiceRoot(service, redpath->version, StatusCode); + if (*StatusCode == NULL || **StatusCode < HTTP_STATUS_200_OK || **StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT) { + cleanupRedPath(redpath); + return root; + } + + if(redpath->next == NULL) + { + cleanupRedPath(redpath); + return root; + } + + FreePool (*StatusCode); + *StatusCode = NULL; + + ret = getPayloadForPath(root, redpath->next, StatusCode); + if (*StatusCode == NULL && ret != NULL) { + // + // In such a case, the Redfish resource is parsed from the input payload (root) directly. + // So, we still return HTTP_STATUS_200_OK. + // + *StatusCode = AllocateZeroPool (sizeof (EFI_HTTP_STATUS_CODE)); + if (*StatusCode == NULL) { + ret = NULL; + } else { + **StatusCode = HTTP_STATUS_200_OK; + } + } + cleanupPayload(root); + cleanupRedPath(redpath); + return ret; +} + +void cleanupServiceEnumerator(redfishService* service) +{ + if(!service) + { + return; + } + free(service->host); + json_decref(service->versions); + if(service->sessionToken != NULL) + { + ZeroMem (service->sessionToken, (UINTN)strlen(service->sessionToken)); + FreePool(service->sessionToken); + } + if (service->basicAuthStr != NULL) { + ZeroMem (service->basicAuthStr, (UINTN)strlen(service->basicAuthStr)); + FreePool (service->basicAuthStr); + } + free(service); +} + +static int initRest(redfishService* service, void * restProtocol) +{ + service->RestEx = restProtocol; + return 0; +} + +static redfishService* createServiceEnumeratorNoAuth(const char* host, const char* rootUri, bool enumerate, unsigned int flags, void * restProtocol) +{ + redfishService* ret; + char *HostStart; + + ret = (redfishService*)calloc(1, sizeof(redfishService)); + ZeroMem (ret, sizeof(redfishService)); + if(initRest(ret, restProtocol) != 0) + { + free(ret); + return NULL; + } + ret->host = AllocateCopyPool(AsciiStrSize(host), host); + ret->flags = flags; + if(enumerate) + { + ret->versions = getVersions(ret, rootUri); + } + HostStart = strstr (ret->host, "//"); + if (HostStart != NULL && (*(HostStart + 2) != '\0')) { + ret->HostHeaderValue = HostStart + 2; + } + + return ret; +} + +EFI_STATUS +createBasicAuthStr ( + IN redfishService* service, + IN CONST CHAR8 *UserId, + IN CONST CHAR8 *Password + ) +{ + EFI_STATUS Status; + CHAR8 *RawAuthValue; + UINTN RawAuthBufSize; + CHAR8 *EnAuthValue; + UINTN EnAuthValueSize; + CHAR8 *BasicWithEnAuthValue; + UINTN BasicBufSize; + + EnAuthValue = NULL; + EnAuthValueSize = 0; + + RawAuthBufSize = AsciiStrLen (UserId) + AsciiStrLen (Password) + 2; + RawAuthValue = AllocatePool (RawAuthBufSize); + if (RawAuthValue == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Build raw AuthValue (UserId:Password). + // + AsciiSPrint ( + RawAuthValue, + RawAuthBufSize, + "%a:%a", + UserId, + Password + ); + + // + // Encoding RawAuthValue into Base64 format. + // + Status = Base64Encode ( + (CONST UINT8 *) RawAuthValue, + AsciiStrLen (RawAuthValue), + EnAuthValue, + &EnAuthValueSize + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + EnAuthValue = (CHAR8 *) AllocateZeroPool (EnAuthValueSize); + if (EnAuthValue == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = Base64Encode ( + (CONST UINT8 *) RawAuthValue, + AsciiStrLen (RawAuthValue), + EnAuthValue, + &EnAuthValueSize + ); + } + + if (EFI_ERROR (Status)) { + goto Exit; + } + + BasicBufSize = AsciiStrLen ("Basic ") + AsciiStrLen(EnAuthValue) + 2; + BasicWithEnAuthValue = AllocatePool (BasicBufSize); + if (BasicWithEnAuthValue == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + // + // Build encoded EnAuthValue with Basic (Basic EnAuthValue). + // + AsciiSPrint ( + BasicWithEnAuthValue, + BasicBufSize, + "%a %a", + "Basic", + EnAuthValue + ); + + service->basicAuthStr = BasicWithEnAuthValue; + +Exit: + if (RawAuthValue != NULL) { + ZeroMem (RawAuthValue, RawAuthBufSize); + FreePool (RawAuthValue); + } + + if (EnAuthValue != NULL) { + ZeroMem (EnAuthValue, EnAuthValueSize); + FreePool (EnAuthValue); + } + + return Status; +} + +static redfishService* createServiceEnumeratorBasicAuth(const char* host, const char* rootUri, const char* username, const char* password, unsigned int flags, void * restProtocol) +{ + redfishService* ret; + EFI_STATUS Status; + + ret = createServiceEnumeratorNoAuth(host, rootUri, false, flags, restProtocol); + + // add basic auth str + Status = createBasicAuthStr (ret, username, password); + if (EFI_ERROR(Status)) { + cleanupServiceEnumerator (ret); + return NULL; + } + + ret->versions = getVersions(ret, rootUri); + return ret; +} + +static redfishService* createServiceEnumeratorSessionAuth(const char* host, const char* rootUri, const char* username, const char* password, unsigned int flags, void * restProtocol) +{ + redfishService* ret; + redfishPayload* payload; + redfishPayload* links; + json_t* sessionPayload; + json_t* session; + json_t* odataId; + const char* uri; + json_t* post; + char* content; + EFI_HTTP_STATUS_CODE *StatusCode; + + content = NULL; + StatusCode = NULL; + + ret = createServiceEnumeratorNoAuth(host, rootUri, true, flags, restProtocol); + if(ret == NULL) + { + return NULL; + } + payload = getRedfishServiceRoot(ret, NULL, &StatusCode); + if(StatusCode == NULL || *StatusCode < HTTP_STATUS_200_OK || *StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT) + { + if (StatusCode != NULL) { + FreePool (StatusCode); + } + + if (payload != NULL) { + cleanupPayload(payload); + } + cleanupServiceEnumerator(ret); + return NULL; + } + + if (StatusCode != NULL) { + FreePool (StatusCode); + StatusCode = NULL; + } + + links = getPayloadByNodeName(payload, "Links", &StatusCode); + cleanupPayload(payload); + if(links == NULL) + { + cleanupServiceEnumerator(ret); + return NULL; + } + session = json_object_get(links->json, "Sessions"); + if(session == NULL) + { + cleanupPayload(links); + cleanupServiceEnumerator(ret); + return NULL; + } + odataId = json_object_get(session, "@odata.id"); + if(odataId == NULL) + { + cleanupPayload(links); + cleanupServiceEnumerator(ret); + return NULL; + } + uri = json_string_value(odataId); + post = json_object(); + addStringToJsonObject(post, "UserName", username); + addStringToJsonObject(post, "Password", password); + content = json_dumps(post, 0); + json_decref(post); + sessionPayload = postUriFromService(ret, uri, content, 0, NULL, &StatusCode); + + if (content != NULL) { + ZeroMem (content, (UINTN)strlen(content)); + free(content); + } + + if(sessionPayload == NULL || StatusCode == NULL || *StatusCode < HTTP_STATUS_200_OK || *StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT) + { + //Failed to create session! + + cleanupPayload(links); + cleanupServiceEnumerator(ret); + + if (StatusCode != NULL) { + FreePool (StatusCode); + } + + if (sessionPayload != NULL) { + json_decref(sessionPayload); + } + + return NULL; + } + json_decref(sessionPayload); + cleanupPayload(links); + FreePool (StatusCode); + return ret; +} + +static char* makeUrlForService(redfishService* service, const char* uri) +{ + char* url; + if(service->host == NULL) + { + return NULL; + } + url = (char*)malloc(strlen(service->host)+strlen(uri)+1); + strcpy(url, service->host); + strcat(url, uri); + return url; +} + +static json_t* getVersions(redfishService* service, const char* rootUri) +{ + json_t* ret = NULL; + EFI_HTTP_STATUS_CODE* StatusCode = NULL; + + if(service->flags & REDFISH_FLAG_SERVICE_NO_VERSION_DOC) + { + service->versions = json_object(); + if(service->versions == NULL) + { + return NULL; + } + addStringToJsonObject(service->versions, "v1", "/redfish/v1"); + return service->versions; + } + if(rootUri != NULL) + { + ret = getUriFromService(service, rootUri, &StatusCode); + } + else + { + ret = getUriFromService(service, "/redfish", &StatusCode); + } + + if (ret == NULL || StatusCode == NULL || *StatusCode < HTTP_STATUS_200_OK || *StatusCode > HTTP_STATUS_206_PARTIAL_CONTENT) { + if (ret != NULL) { + json_decref(ret); + } + ret = NULL; + } + + if (StatusCode != NULL) { + FreePool (StatusCode); + } + + return ret; +} + +static void addStringToJsonObject(json_t* object, const char* key, const char* value) +{ + json_t* jValue = json_string(value); + + json_object_set(object, key, jValue); + + json_decref(jValue); +} diff --git a/CdeEmuPkg/RedfishPkg/Readme.md b/CdeEmuPkg/RedfishPkg/Readme.md new file mode 100644 index 00000000000..d59ca953b1f --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Readme.md @@ -0,0 +1,133 @@ +# UEFI Redfish EDK2 Implementation + +## Introduction +UEFI Redfish EDK2 solution is an efficient and secure solution for the end-users to remote configure (in Out-of-band) UEFI platform configurations by leveraging the Redfish RESTful API. It's simple for end-users to access the configurations of UEFI firmware which have the equivalent properties defined in Redfish schema. + +Below are the block diagrams of UEFI Redfish EDK2 Implementation. ***[EDK2 Redfish Foundation[1]](#[0])*** in the lower part of the figure refers to the EDK2 Redfish Foundation, which provides the fundamental EDK2 drivers to communicate with Redfish service ***([[19]](#[0]) in the above figure)***. The Redfish service could be implemented in BMC to manage the system, or on the network for managing multiple systems. + +***[EDK2 Redfish Client[2]](#[0])*** in the upper part of the figure refers to the EDK2 Redfish client, which is the EDK2 Redfish application used to configure platform configurations by consuming the Redfish properties. The EDK2 Redfish client can also provision the UEFI platform-owned Redfish properties, consume and update Redfish properties as well. The ***[EDK2 Redfish Feature DXE Drivers [17]](https://github.com/tianocore/edk2-staging/blob/edk2-redfish-client/RedfishClientPkg/Readme.md)*** is the project under development in EDK2 staging repository. Each EDK2 Redfish Feature DXE Driver is designed to communicate with the particular Redfish data model defined in the Redfish schema *(e.g. Edk2RedfishBiosDxe driver manipulates the properties defined in Redfish BIOS data model)*. + +## EDK2 Redfish Implementation Diagrams +![UEFI Redfish Implementation](https://github.com/tianocore/edk2/blob/master/RedfishPkg/Documents/Media/RedfishDriverStack.svg?raw=true) + +## EFI EDK2 Redfish Driver Stack +Below are the EDK2 drivers implemented on EDK2, + +### EDK2 Redfish Host Interface DXE Driver ***[[6]](#[0])*** + +The abstract EDK2 DXE driver to create SMBIOS type 42 record through EFI SMBIOS protocol according to the device descriptor and protocol type data (defined in SMBIOS type 42h ***[[7]](#[0])***) provided by platform level Redfish host interface library. On EDK2 open source implementation (**EmulatorPkg**), SMBIOS type 42 data is retrieved from EFI variables created by RedfishPlatformConfig.efi ***[[20]](#[0])*** under EFI shell. OEM may provide its own PlatformHostInterfaceLib ***[[11]](#[0])*** instance for the platform-specific implementation. + +### EDK2 Refish Credential DXE Driver ***[[5]](#[0])*** + +The abstract DXE driver which incorporates with RedfishPlatformCredentialLib ***[[10]](#[0])*** to acquire the credential of Redfish service. On edk2 EmulatorPkg implementation, the credential is hardcoded using the fixed Account/Password in order to connect to Redfish service established by [Redfish Profile Simulator](https://github.com/DMTF/Redfish-Profile-Simulator). OEM may provide its own RedfishPlatformCredentialLib instance for the platform-specific implementation. + +### EFI REST EX UEFI Driver for Redfish service ***[[4]](#[0])*** + +This is the network-based driver instance of EFI_REST_EX protocol [(UEFI spec 2.8, section 29.7.2)](http://uefi.org/specifications) for communicating with Redfish service using the HTTP protocol. OEM may have its own EFI REST EX UEFI Driver instance on which the underlying transport to Redfish service could be proprietary. + +### EFI Redfish Discover UEFI Driver ***[[3]](#[0])*** + +EFI Redfish Discover Protocol implementation (UEFI spec 2.8, section 31.1). Only support Redfish service discovery through Redfish Host Interface. The Redfish service discovery using SSDP over UDP ***[[18]](#[0])*** is not implemented at the moment. + +### EFI REST JSON Structure DXE Driver ***[[9]](#[0])*** + +EFI REST JSON Structure DXE implementation (UEFI spec 2.8, section 29.7.3). This could be used by EDK2 Redfish Feature DXE Drivers ***[[17]](#[0])***. The EDK2 Redfish feature drivers manipulate platform-owned Redfish properties in C structure format and convert them into the payload in JSON format through this protocol. This driver leverages the effort of [Redfish Schema to C Generator](https://github.com/DMTF/Redfish-Schema-C-Struct-Generator) to have the "C Structure" <-> "JSON" conversion. + +### EDK2 Redfish Config Handler UEFI Driver ***[[15]](#[0])*** + +This is the centralized manager of EDK2 Redfish feature drivers, it initiates EDK2 Redfish feature drivers by invoking init() function of EDK2 Redfish Config Handler Protocol ***[[16]](#[0])*** installed by each EDK2 Redfish feature driver. EDK2 Redfish Config Handler driver is an UEFI driver which has the dependency with EFI REST EX protocol and utilizes EFI Redfish Discover protocol to discover Redfish service that manages this system. + +### EDK2 Content Coding Library ***[[12]](#[0])*** +The library is incorporated with RedfishLib ***[[13]](#[0])*** to encode and decode Redfish JSON payload. This is the platform library to support HTTP Content-Encoding/Accept-Encoding headers. EumlatorPkg use the NULL instance of this library because [Redfish Profile Simulator](https://github.com/DMTF/Redfish-Profile-Simulator) supports neither HTTP Content-Encoding header on the payload returned to Redfish client nor HTTP Accept-Encoding header. + +## Other Open Source Projects + The following libraries are the wrappers of other open source projects used in RedfishPkg + + * **RedfishPkg\PrivateLibrary\RedfishLib** ***[[13]](#[0])*** + This is the wrapper of open source project ***[libredfish](https://github.com/DMTF/libredfish)***, + which is the library to initialize the connection to Redfish service with the proper credential and execute Create/Read/Update/Delete (CRUD) HTTP methods on Redfish properties. + + * **RedfishPkg\Library\JsonLib** ***[[14]](#[0])*** + This is the wrapper of open source project ***[Jansson](https://digip.org/jansson)***, which is the library that provides APIs to manipulate JSON payload. + +## Platform Components for EDK2 EmulatorPkg: + * **RedfishPlatformCredentialLib** + the EDK2 Emulator platform implementation of acquiring credential to build up the communication between UEFI firmware and Redfish service. ***[[10]](#[0])*** + + * **RedfishPlatformHostInterfaceLib** + EDK2 Emulator platform implementation which provides the information of building up SMBIOS type 42h record. ***[[11]](#[0])*** + +## Miscellaneous: + + * **EFI Shell Application** + RedfishPlatformConfig.exe is an EFI Shell application used to set up the Redfish service information for the EDK2 Emulator platform. The information such as IP address, subnet, and port. + ```C + For example, run shell command "RedfishPlatformConfig.efi -s 192.168.10.101 255.255.255.0 192.168.10.123 255.255.255.0", which means + the source IP address is 192.168.10.101, and the Redfish Server IP address is 192.168.10.123. + ``` + + * **Redfish Profile Simulator** + Refer to [Redfish Profile Simulator](https://github.com/DMTF/Redfish-Profile-Simulator) to set up the Redfish service. + We are also in the progress to contribute bug fixes and enhancements to the mainstream Redfish Profile Simulator in order to incorporate with EDK2 Redfish solution. + +## Connect to Redfish Service on EDK2 Emulator Platform + 1. Install the WinpCap and copy [SnpNt32Io.dll](https://github.com/tianocore/edk2-NetNt32Io) to the building directory of the Emulator platform. This is the emulated network interface for EDK2 Emulator Platform. + ```C + e.g. %WORKSPACE%/Build/EmulatorX64/DEBUG_VS2015x86/X64 + ``` + + 2. Enable below macros in EmulatorPkg.dsc + ```C + NETWORK_SNP_ENABLE = TRUE + NETWORK_HTTP_ENABLE = TRUE + NETWORK_IP6_ENABLE = TRUE + SECURE_BOOT_ENABLE = TRUE + REDFISH_ENABLE = TRUE + ``` + + 3. Allow HTTP connection + Enable below macro to allow HTTP connection on EDK2 network stack for connecting to [Redfish Profile Simulator](https://github.com/DMTF/Redfish-Profile-Simulator) becasue Redfish Profile Simulator doesn't support HTTPS. + ```C + NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE + ``` + + 4. Assign the correct MAC Address + Assign the correct MAC address of the network interface card emulated by WinpCap. + - Rebuild EmulatorPkg and boot to EFI shell once SnpNt32Io.dll is copied to the building directory and the macros mentioned in #2 are all set to TURE. + - Execute the EFI shell command "ifconfig -l" under EFI shell and look for MAC address information, then assign the MAC address to below PCD. + ```c + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceDevicePath.DevicePath|{DEVICE_PATH("MAC(000000000000,0x1)")} + ``` + + - Assign the network adapter instaleld on the host (working machine) that will be emulated as the network interface in edk2 Emulator. + + ```c + # + # For Windows based host, use a number to refer to network adapter + # + gEmulatorPkgTokenSpaceGuid.PcdEmuNetworkInterface|L"1" + or + # + # For Linux based host, use the device name of network adapter + # + gEmulatorPkgTokenSpaceGuid.PcdEmuNetworkInterface|L"en0" + ``` + + 5. Configure the Redfish service on the EDK2 Emulator platform + + Execute RedfishPlatformConfig.efi under EFI shell to configure the Redfish service information. The EFI variables are created for storing Redfish service information and is consumed by RedfishPlatformHostInterfaceLib under EmulatorPkg. + +## Related Materials +1. [DSP0270](https://www.dmtf.org/sites/default/files/standards/documents/DSP0270_1.3.0.pdf) - Redfish Host Interface Specification, 1.3.0 +2. [DSP0266](https://www.dmtf.org/sites/default/files/standards/documents/DSP0266_1.12.0.pdf) - Redfish Specification, 1.12.0 +3. Redfish Schemas - https://redfish.dmtf.org/schemas/v1/ +4. UEFI Specification - http://uefi.org/specifications + +## The Contributors +Thanks to the below predecessors who contributed to the UEFI EDK2 Redfish Prove of Concept code.\ +Fu, Siyuan \ +Ye, Ting \ +Wang, Fan \ +Wu, Jiaxin \ +Yao, Jiewen \ +Shia, Cinnamon diff --git a/CdeEmuPkg/RedfishPkg/Redfish.dsc.inc b/CdeEmuPkg/RedfishPkg/Redfish.dsc.inc new file mode 100644 index 00000000000..da8a4a9b277 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Redfish.dsc.inc @@ -0,0 +1,21 @@ +## @file +# Redfish DSC include file for Platform DSC +# +# This file includes all required information to enable Redfish features. +# It can be included to a platform DSC file by using "!include RedfishPkg/Redfish.dsc.inc". +# +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + !include RedfishPkg/RedfishDefines.dsc.inc + +[LibraryClasses] + !include RedfishPkg/RedfishLibs.dsc.inc + +[Components] + !include RedfishPkg/RedfishComponents.dsc.inc + diff --git a/CdeEmuPkg/RedfishPkg/Redfish.fdf.inc b/CdeEmuPkg/RedfishPkg/Redfish.fdf.inc new file mode 100644 index 00000000000..21754f008c6 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/Redfish.fdf.inc @@ -0,0 +1,20 @@ +## @file +# Redfish FDF include file for [FV*] section of all Architectures. +# +# This file can be included to the [FV*] section(s) of a platform FDF file +# by using "!include RedfishPkg/RedfisLibs.fdf.inc" to specify the module instances +# to be built in the firmware volume. +# +# (C) Copyright 2020-2021 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +!if $(REDFISH_ENABLE) == TRUE + INF RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.inf + INF RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf + INF RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf + INF RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf + INF RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.inf + INF RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.inf +!endif diff --git a/CdeEmuPkg/RedfishPkg/RedfishComponents.dsc.inc b/CdeEmuPkg/RedfishPkg/RedfishComponents.dsc.inc new file mode 100644 index 00000000000..81b5e6b8f58 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishComponents.dsc.inc @@ -0,0 +1,22 @@ +## @file +# Redfish DSC include file for [Components*] section of all Architectures. +# +# This file can be included to the [Components*] section(s) of a platform DSC file +# by using "!include RedfishPkg/RedfishComponents.dsc.inc" to specify the INF files +# of EDKII Redfish drivers according to the value of flags described in +# "RedfishDefines.dsc.inc". +# +# (C) Copyright 2020-2021 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +!if $(REDFISH_ENABLE) == TRUE + RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.inf + RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf + RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf + RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf + RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.inf + RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.inf +!endif diff --git a/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.c b/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.c new file mode 100644 index 00000000000..ca10a84daea --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.c @@ -0,0 +1,265 @@ +/** @file + The common code of EDKII Redfish Configuration Handler driver. + + (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "RedfishConfigHandlerCommon.h" + +REDFISH_CONFIG_DRIVER_DATA gRedfishConfigData; // Only one Redfish service supproted + // on platform for the BIOS + // Redfish configuration. +EFI_EVENT gEndOfDxeEvent = NULL; +EFI_EVENT gExitBootServiceEvent = NULL; +EDKII_REDFISH_CREDENTIAL_PROTOCOL *gCredential = NULL; + +/** + Callback function executed when the EndOfDxe event group is signaled. + + @param[in] Event Event whose notification function is being invoked. + @param[out] Context Pointer to the Context buffer. + +**/ +VOID +EFIAPI +RedfishConfigOnEndOfDxe ( + IN EFI_EVENT Event, + OUT VOID *Context + ) +{ + EFI_STATUS Status; + + Status = gCredential->StopService (gCredential, ServiceStopTypeSecureBootDisabled); + if (EFI_ERROR(Status) && Status != EFI_UNSUPPORTED) { + DEBUG ((DEBUG_ERROR, "Redfish credential protocol faied to stop service on EndOfDxe: %r", Status)); + } + + // + // Close event, so it will not be invoked again. + // + gBS->CloseEvent (gEndOfDxeEvent); + gEndOfDxeEvent = NULL; +} + +/** + Callback function executed when the ExitBootService event group is signaled. + + @param[in] Event Event whose notification function is being invoked. + @param[out] Context Pointer to the Context buffer + +**/ +VOID +EFIAPI +RedfishConfigOnExitBootService ( + IN EFI_EVENT Event, + OUT VOID *Context + ) +{ + EFI_STATUS Status; + + Status = gCredential->StopService (gCredential, ServiceStopTypeExitBootService); + if (EFI_ERROR(Status) && Status != EFI_UNSUPPORTED) { + DEBUG ((DEBUG_ERROR, "Redfish credential protocol faied to stop service on ExitBootService: %r", Status)); + } +} + +/** + Unloads an image. + + @param[in] ImageHandle Handle that identifies the image to be unloaded. + + @retval EFI_SUCCESS The image has been unloaded. + +**/ +EFI_STATUS +RedfishConfigDriverCommonUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + if (gEndOfDxeEvent != NULL) { + gBS->CloseEvent (gEndOfDxeEvent); + gEndOfDxeEvent = NULL; + } + + if (gExitBootServiceEvent != NULL) { + gBS->CloseEvent (gExitBootServiceEvent); + gExitBootServiceEvent = NULL; + } + + if (gRedfishConfigData.Event != NULL) { + gBS->CloseEvent (gRedfishConfigData.Event); + gRedfishConfigData.Event = NULL; + } + + return EFI_SUCCESS; +} + +/** + This is the common code for Redfish configuration UEFI and DXE driver + initialization. + + @param[in] ImageHandle The firmware allocated handle for the UEFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval Others An unexpected error occurred. +**/ +EFI_STATUS +RedfishConfigCommonInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + // + // Locate Redfish Credential Protocol to get credential for + // accessing to Redfish service. + // + Status = gBS->LocateProtocol (&gEdkIIRedfishCredentialProtocolGuid, NULL, (VOID **) &gCredential); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a: No Redfish Credential Protocol is installed on system.", __FUNCTION__)); + return Status; + } + // + // Create EndOfDxe Event. + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + RedfishConfigOnEndOfDxe, + NULL, + &gEfiEndOfDxeEventGroupGuid, + &gEndOfDxeEvent + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to register End Of DXE event.", __FUNCTION__)); + return Status; + } + // + // Create Exit Boot Service event. + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + RedfishConfigOnExitBootService, + NULL, + &gEfiEventExitBootServicesGuid, + &gExitBootServiceEvent + ); + if (EFI_ERROR (Status)) { + gBS->CloseEvent (gEndOfDxeEvent); + gEndOfDxeEvent = NULL; + DEBUG ((DEBUG_ERROR, "%a: Fail to register Exit Boot Service event.", __FUNCTION__)); + return Status; + } + return EFI_SUCCESS; +} +/** + This is the common code to stop EDK2 Redfish feature driver. + + @retval EFI_SUCCESS All EDK2 Redfish feature drivers are + stopped. + @retval Others An unexpected error occurred. +**/ +EFI_STATUS +RedfishConfigCommonStop ( + VOID +) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + UINTN Index; + EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *ConfigHandler; + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEdkIIRedfishConfigHandlerProtocolGuid, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) { + return Status; + } + + Status = EFI_SUCCESS; + for (Index = 0; Index < NumberOfHandles; Index++) { + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEdkIIRedfishConfigHandlerProtocolGuid, + (VOID**) &ConfigHandler + ); + ASSERT_EFI_ERROR (Status); + + Status = ConfigHandler->Stop (ConfigHandler); + if (EFI_ERROR (Status) && Status != EFI_UNSUPPORTED) { + DEBUG ((DEBUG_ERROR, "ERROR: Failed to stop Redfish config handler %p.\n", ConfigHandler)); + break; + } + } + return Status; +} +/** + Callback function executed when a Redfish Config Handler Protocol is installed + by EDK2 Redfish Feature Drivers. + +**/ +VOID +RedfishConfigHandlerInitialization ( + VOID + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *ConfigHandler; + UINTN Index; + UINT32 Id; + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEdkIIRedfishConfigHandlerProtocolGuid, + NULL, + &NumberOfHandles, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return; + } + + for (Index = 0; Index < NumberOfHandles; Index++) { + Status = gBS->HandleProtocol ( + HandleBuffer [Index], + &gEfiCallerIdGuid, + (VOID **) &Id + ); + if (!EFI_ERROR (Status)) { + continue; + } + + Status = gBS->HandleProtocol ( + HandleBuffer [Index], + &gEdkIIRedfishConfigHandlerProtocolGuid, + (VOID**) &ConfigHandler + ); + ASSERT_EFI_ERROR (Status); + Status = ConfigHandler->Init (ConfigHandler, &gRedfishConfigData.RedfishServiceInfo); + if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) { + DEBUG ((DEBUG_ERROR, "ERROR: Failed to init Redfish config handler %p.\n", ConfigHandler)); + } + // + // Install caller ID to indicate Redfish Configure Handler is initialized. + // + Status = gBS->InstallProtocolInterface ( + &HandleBuffer [Index], + &gEfiCallerIdGuid, + EFI_NATIVE_INTERFACE, + (VOID *)&gRedfishConfigData.CallerId + ); + ASSERT_EFI_ERROR (Status); + } +} diff --git a/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.h b/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.h new file mode 100644 index 00000000000..32a3cace4bd --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.h @@ -0,0 +1,101 @@ +/** @file + Common Header file for Redfish Configuration Handler UEFI driver + and DXE driver. + + (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EFI_REDFISH_CONFIG_HANDLER_COMMON_H_ +#define EFI_REDFISH_CONFIG_HANDLER_COMMON_H_ + +#include + +// +// Libraries +// +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Consumed Protocols +// +#include +#include + +// +// Driver Version +// +#define REDFISH_CONFIG_VERSION 0x00000001 + +/// +/// Internal structure used by Redfish Config DXE driver. +/// +typedef struct { + UINT32 CallerId; ///< Caller ID used to indicate Redfish Config Handler + ///< has been initiated + EFI_HANDLE Image; ///< Image handle of Redfish Config Driver + EFI_EVENT Event; ///< Event for the notification of EFI_REDFISH_CONFIG_HANDLER_PROTOCOL + REDFISH_CONFIG_SERVICE_INFORMATION RedfishServiceInfo; /// Redfish Service information discovered +} REDFISH_CONFIG_DRIVER_DATA; + +/** + Common code of unloading image for both UEFI/DXE Redfish Configuration drivers. + + @param[in] ImageHandle Handle that identifies the image to be unloaded. + + @retval EFI_SUCCESS The image has been unloaded. + +**/ +EFI_STATUS +RedfishConfigDriverCommonUnload ( + IN EFI_HANDLE ImageHandle + ); + +/** + This is the common code for Redfish configuration UEFI and DXE driver + initialization. + + @param[in] ImageHandle The firmware allocated handle for the UEFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval Others An unexpected error occurred. +**/ +EFI_STATUS +RedfishConfigCommonInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + This is the common code to stop EDK2 Redfish feature driver. + + @retval EFI_SUCCESS All EDK2 Redfish feature drivers are + stopped. + @retval Others An unexpected error occurred. +**/ +EFI_STATUS +RedfishConfigCommonStop ( + VOID +); + +/** + Callback function executed when a Redfish Config Handler Protocol is installed + by EDK2 Redfish Feature Drivers. + +**/ +VOID +RedfishConfigHandlerInitialization ( + VOID + ); + +#endif diff --git a/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c b/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c new file mode 100644 index 00000000000..2bcd1dc981c --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c @@ -0,0 +1,615 @@ +/** @file + The UEFI driver model driver which is responsible for locating the + Redfish service through Redfish host interface and executing EDKII + Redfish feature drivers. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "RedfishConfigHandlerDriver.h" + +#include +#include + +EFI_EVENT gEfiRedfishDiscoverProtocolEvent = NULL; + +// +// Variables for using RFI Redfish Discover Protocol +// +VOID *gEfiRedfishDiscoverRegistration; +EFI_HANDLE gEfiRedfishDiscoverControllerHandle = NULL; +EFI_REDFISH_DISCOVER_PROTOCOL *gEfiRedfishDiscoverProtocol = NULL; +BOOLEAN gRedfishDiscoverActivated = FALSE; +BOOLEAN gRedfishServiceDiscovered = FALSE; +// +// Network interfaces discovered by EFI Redfish Discover Protocol. +// +UINTN gNumberOfNetworkInterfaces; +EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *gNetworkInterfaceInstances = NULL; +EFI_REDFISH_DISCOVERED_TOKEN *gRedfishDiscoveredToken = NULL; + +/// +/// Driver Binding Protocol instance +/// +EFI_DRIVER_BINDING_PROTOCOL gRedfishConfigDriverBinding = { + RedfishConfigDriverBindingSupported, + RedfishConfigDriverBindingStart, + RedfishConfigDriverBindingStop, + REDFISH_CONFIG_VERSION, + NULL, + NULL +}; + +/** + Stop acquiring Redfish service. + +**/ +VOID +RedfishConfigStopRedfishDiscovery ( + VOID +) +{ + if (gRedfishDiscoverActivated) { + // + // No more EFI Discover Protocol. + // + if (gEfiRedfishDiscoverProtocolEvent != NULL) { + gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent); + } + // + // Stop Redfish service discovery. + // + gEfiRedfishDiscoverProtocol->AbortAcquireRedfishService ( + gEfiRedfishDiscoverProtocol, + gNetworkInterfaceInstances + ); + gEfiRedfishDiscoverControllerHandle = NULL; + gEfiRedfishDiscoverProtocol = NULL; + gRedfishDiscoverActivated = FALSE; + gRedfishServiceDiscovered = FALSE; + } +} + +/** + Callback function executed when a Redfish Config Handler Protocol is installed. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the REDFISH_CONFIG_DRIVER_DATA buffer. + +**/ +VOID +EFIAPI +RedfishConfigHandlerInstalledCallback ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + if (!gRedfishDiscoverActivated) { + // + // No Redfish service is discovered yet. + // + return; + } + + RedfishConfigHandlerInitialization (); +} + +/** + 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_UNSUPPORTED The device specified by ControllerHandle and + RemainingDevicePath is not supported by the driver specified by This. +**/ +EFI_STATUS +EFIAPI +RedfishConfigDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + EFI_REST_EX_PROTOCOL *RestEx; + EFI_STATUS Status; + EFI_HANDLE ChildHandle; + + ChildHandle = NULL; + + // + // Check if REST EX is ready. This just makes sure + // the network stack is brought up. + // + Status = NetLibCreateServiceChild ( + ControllerHandle, + This->ImageHandle, + &gEfiRestExServiceBindingProtocolGuid, + &ChildHandle + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + // + // Test if REST EX protocol is ready. + // + Status = gBS->OpenProtocol( + ChildHandle, + &gEfiRestExProtocolGuid, + (VOID**) &RestEx, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + Status = EFI_UNSUPPORTED; + } + NetLibDestroyServiceChild ( + ControllerHandle, + This->ImageHandle, + &gEfiRestExServiceBindingProtocolGuid, + ChildHandle + ); + 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 driver is started. + @retval EFI_ALREADY_STARTED The driver was already started. + +**/ +EFI_STATUS +EFIAPI +RedfishConfigDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + VOID *ConfigHandlerRegistration; + + if (gRedfishConfigData.Event != NULL) { + return EFI_ALREADY_STARTED; + } + + gRedfishConfigData.Event = EfiCreateProtocolNotifyEvent ( + &gEdkIIRedfishConfigHandlerProtocolGuid, + TPL_CALLBACK, + RedfishConfigHandlerInstalledCallback, + (VOID *)&gRedfishConfigData, + &ConfigHandlerRegistration + ); + return EFI_SUCCESS; +} + +/** + 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 +RedfishConfigDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +{ + EFI_STATUS Status; + + if (ControllerHandle == gEfiRedfishDiscoverControllerHandle) { + RedfishConfigStopRedfishDiscovery (); + } + gBS->CloseProtocol ( + ControllerHandle, + &gEfiRedfishDiscoverProtocolGuid, + gRedfishConfigData.Image, + gRedfishConfigData.Image + ); + + Status = RedfishConfigCommonStop (); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + if (gRedfishConfigData.Event != NULL) { + gBS->CloseEvent (gRedfishConfigData.Event); + gRedfishConfigData.Event = NULL; + } + return EFI_SUCCESS; +} + +/** + Callback function when Redfish service is discovered. + + @param[in] Event Event whose notification function is being invoked. + @param[out] Context Pointer to the Context buffer + +**/ +VOID +EFIAPI +RedfishServiceDiscoveredCallback ( + IN EFI_EVENT Event, + OUT VOID *Context + ) +{ + EFI_REDFISH_DISCOVERED_TOKEN *RedfishDiscoveredToken; + EFI_REDFISH_DISCOVERED_INSTANCE *RedfishInstance; + + if (gRedfishServiceDiscovered) { + // + // Only support one Redfish service on platform. + // + return; + } + + RedfishDiscoveredToken = (EFI_REDFISH_DISCOVERED_TOKEN *)Context; + RedfishInstance = RedfishDiscoveredToken->DiscoverList.RedfishInstances; + // + // Only pick up the first found Redfish service. + // + if (RedfishInstance->Status == EFI_SUCCESS) { + gRedfishConfigData.RedfishServiceInfo.RedfishServiceRestExHandle = RedfishInstance->Information.RedfishRestExHandle; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceVersion = RedfishInstance->Information.RedfishVersion; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceLocation = RedfishInstance->Information.Location; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceUuid = RedfishInstance->Information.Uuid; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceOs = RedfishInstance->Information.Os; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceOsVersion = RedfishInstance->Information.OsVersion; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceProduct = RedfishInstance->Information.Product; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceProductVer = RedfishInstance->Information.ProductVer; + gRedfishConfigData.RedfishServiceInfo.RedfishServiceUseHttps = RedfishInstance->Information.UseHttps; + gRedfishServiceDiscovered = TRUE; + } + + // + // Invoke RedfishConfigHandlerInstalledCallback to execute + // the initialization of Redfish Configure Handler instance. + // + RedfishConfigHandlerInstalledCallback (gRedfishConfigData.Event, &gRedfishConfigData); +} + +/** + Callback function executed when the EFI_REDFISH_DISCOVER_PROTOCOL + protocol interface is installed. + + @param[in] Event Event whose notification function is being invoked. + @param[out] Context Pointer to the Context buffer + +**/ +VOID +EFIAPI +RedfishDiscoverProtocolInstalled ( + IN EFI_EVENT Event, + OUT VOID *Context + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + EFI_HANDLE HandleBuffer; + UINTN NetworkInterfaceIndex; + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *ThisNetworkInterface; + EFI_REDFISH_DISCOVERED_TOKEN *ThisRedfishDiscoveredToken; + + DEBUG((DEBUG_INFO, "%a: New network interface is installed on system by EFI Redfish discover driver.\n", __FUNCTION__)); + + BufferSize = sizeof (EFI_HANDLE); + Status = gBS->LocateHandle ( + ByRegisterNotify, + NULL, + gEfiRedfishDiscoverRegistration, + &BufferSize, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "%a: Can't locate handle with EFI_REDFISH_DISCOVER_PROTOCOL installed.\n", __FUNCTION__)); + } + gRedfishDiscoverActivated = TRUE; + if (gEfiRedfishDiscoverProtocol == NULL) { + gEfiRedfishDiscoverControllerHandle = HandleBuffer; + // + // First time to open EFI_REDFISH_DISCOVER_PROTOCOL. + // + Status = gBS->OpenProtocol( + gEfiRedfishDiscoverControllerHandle, + &gEfiRedfishDiscoverProtocolGuid, + (VOID **)&gEfiRedfishDiscoverProtocol, + gRedfishConfigData.Image, + gRedfishConfigData.Image, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + gEfiRedfishDiscoverProtocol = NULL; + gRedfishDiscoverActivated = FALSE; + DEBUG((DEBUG_ERROR, "%a: Can't locate EFI_REDFISH_DISCOVER_PROTOCOL.\n", __FUNCTION__)); + return; + } + } + // + // Check the new found network interface. + // + if (gNetworkInterfaceInstances != NULL) { + FreePool (gNetworkInterfaceInstances); + } + Status = gEfiRedfishDiscoverProtocol->GetNetworkInterfaceList( + gEfiRedfishDiscoverProtocol, + gRedfishConfigData.Image, + &gNumberOfNetworkInterfaces, + &gNetworkInterfaceInstances + ); + if (EFI_ERROR (Status) || gNumberOfNetworkInterfaces == 0) { + DEBUG((DEBUG_ERROR, "%a: No network interfaces found on the handle.\n", __FUNCTION__)); + return; + } + + gRedfishDiscoveredToken = AllocateZeroPool (gNumberOfNetworkInterfaces * sizeof (EFI_REDFISH_DISCOVERED_TOKEN)); + if (gRedfishDiscoveredToken == NULL) { + DEBUG((DEBUG_ERROR, "%a: Not enough memory for EFI_REDFISH_DISCOVERED_TOKEN.\n", __FUNCTION__)); + return; + } + + ThisNetworkInterface = gNetworkInterfaceInstances; + ThisRedfishDiscoveredToken = gRedfishDiscoveredToken; + // + // Loop to discover Redfish service on each network interface. + // + for (NetworkInterfaceIndex = 0; NetworkInterfaceIndex < gNumberOfNetworkInterfaces; NetworkInterfaceIndex ++) { + // + // Initial this Redfish Discovered Token + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + RedfishServiceDiscoveredCallback, + (VOID *)ThisRedfishDiscoveredToken, + &ThisRedfishDiscoveredToken->Event + ); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "%a: Failed to create event for Redfish discovered token.\n", __FUNCTION__)); + goto ErrorReturn; + } + ThisRedfishDiscoveredToken->Signature = REDFISH_DISCOVER_TOKEN_SIGNATURE; + ThisRedfishDiscoveredToken->DiscoverList.NumberOfServiceFound = 0; + ThisRedfishDiscoveredToken->DiscoverList.RedfishInstances = NULL; + // + // Acquire for Redfish service which is reported by + // Redfish Host Interface. + // + Status = gEfiRedfishDiscoverProtocol->AcquireRedfishService( + gEfiRedfishDiscoverProtocol, + gRedfishConfigData.Image, + ThisNetworkInterface, + EFI_REDFISH_DISCOVER_HOST_INTERFACE, + ThisRedfishDiscoveredToken + ); + ThisNetworkInterface ++; + ThisRedfishDiscoveredToken ++; + } + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "%a: Acquire Redfish service fail.\n", __FUNCTION__)); + goto ErrorReturn; + } + return; + +ErrorReturn: + if (gRedfishDiscoveredToken != NULL) { + FreePool(gRedfishDiscoveredToken); + } +} + +/** + Unloads an image. + + @param[in] ImageHandle Handle that identifies the image to be unloaded. + + @retval EFI_SUCCESS The image has been unloaded. + +**/ +EFI_STATUS +EFIAPI +RedfishConfigHandlerDriverUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_REDFISH_DISCOVERED_TOKEN *ThisRedfishDiscoveredToken; + UINTN NumberOfNetworkInterfacesIndex; + + RedfishConfigDriverCommonUnload (ImageHandle); + + RedfishConfigStopRedfishDiscovery (); + if (gRedfishDiscoveredToken != NULL) { + ThisRedfishDiscoveredToken = gRedfishDiscoveredToken; + for (NumberOfNetworkInterfacesIndex = 0; NumberOfNetworkInterfacesIndex < gNumberOfNetworkInterfaces; NumberOfNetworkInterfacesIndex ++) { + if (ThisRedfishDiscoveredToken->Event != NULL) { + gBS->CloseEvent (ThisRedfishDiscoveredToken->Event); + } + FreePool (ThisRedfishDiscoveredToken); + ThisRedfishDiscoveredToken ++; + } + gRedfishDiscoveredToken = NULL; + } + return EFI_SUCCESS; +} + +/** + 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[in] ImageHandle The firmware allocated handle for the UEFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval Others An unexpected error occurred. +**/ +//EFI_STATUS +//EFIAPI +//RedfishConfigHandlerDriverEntryPoint ( +// IN EFI_HANDLE ImageHandle, +// IN EFI_SYSTEM_TABLE *SystemTable +// ) +//{ + +EFI_STATUS main(int argc, char** argv) +{ + EFI_STATUS Status; + if(1) + { + volatile long long ll = 3; + + while(ll / argc); + } + EFI_HANDLE ImageHandle = (void*)argv[-2]; + IN EFI_SYSTEM_TABLE* SystemTable = (void*)argv[-1]; + // + // CdePkg demo + // + if (1) { + extern CHAR8* gEfiCallerBaseName; + int i; + + for (i = 0; i < argc; i++) // search upcase "/DEBUGBREAK" in arguments + if(0 == strcmp("/DEBUGBREAK", argv[i])) + __debugbreak(); + + for (i = 0; i < argc; i++) + printf("### CdePkg demo ### gEfiCallerBaseName: \"%s\" argv[%d] %s\n", gEfiCallerBaseName, i, argv[i]); + + } + ZeroMem ((VOID *)&gRedfishConfigData, sizeof (REDFISH_CONFIG_DRIVER_DATA)); + gRedfishConfigData.Image = ImageHandle; + // + // Register event for EFI_REDFISH_DISCOVER_PROTOCOL protocol install + // notification. + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + RedfishDiscoverProtocolInstalled, + NULL, + &gEfiRedfishDiscoverProtocolGuid, + &gEfiRedfishDiscoverProtocolEvent + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to create event for the installation of EFI_REDFISH_DISCOVER_PROTOCOL.", __FUNCTION__)); + return Status; + } + Status = gBS->RegisterProtocolNotify ( + &gEfiRedfishDiscoverProtocolGuid, + gEfiRedfishDiscoverProtocolEvent, + &gEfiRedfishDiscoverRegistration + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to register event for the installation of EFI_REDFISH_DISCOVER_PROTOCOL.", __FUNCTION__)); + return Status; + } + + Status = RedfishConfigCommonInit (ImageHandle, SystemTable); + if (EFI_ERROR (Status)) { + gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent); + gEfiRedfishDiscoverProtocolEvent = NULL; + return Status; + } + + // + // Install UEFI Driver Model protocol(s). + // + Status = EfiLibInstallDriverBinding ( + ImageHandle, + SystemTable, + &gRedfishConfigDriverBinding, + ImageHandle + ); + if (EFI_ERROR (Status)) { + gBS->CloseEvent (gEndOfDxeEvent); + gEndOfDxeEvent = NULL; + gBS->CloseEvent (gExitBootServiceEvent); + gExitBootServiceEvent = NULL; + gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent); + gEfiRedfishDiscoverProtocolEvent = NULL; + DEBUG ((DEBUG_ERROR, "%a: Fail to install EFI Binding Protocol of EFI Redfish Config driver.", __FUNCTION__)); + return Status; + } + return Status; +} + diff --git a/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.h b/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.h new file mode 100644 index 00000000000..d0ee0adecfd --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.h @@ -0,0 +1,159 @@ +/** @file + Header file of Redfish Configuration Handler UEFI driver. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EFI_REDFISH_CONFIG_HANDLER_DRIVER_H_ +#define EFI_REDFISH_CONFIG_HANDLER_DRIVER_H_ + +#include "RedfishConfigHandlerCommon.h" + +// +// UEFI Driver Model Protocols +// + +#include +#include +#include + +// +// Protocol instances +// +extern EFI_DRIVER_BINDING_PROTOCOL gRedfishConfigDriverBinding; + +extern REDFISH_CONFIG_DRIVER_DATA gRedfishConfigData; +extern EDKII_REDFISH_CREDENTIAL_PROTOCOL *gCredential; +extern EFI_EVENT gEndOfDxeEvent; +extern EFI_EVENT gExitBootServiceEvent; + +/** + 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 +RedfishConfigDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +/** + 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 driver is started. + @retval EFI_ALREADY_STARTED The driver was already started. + +**/ +EFI_STATUS +EFIAPI +RedfishConfigDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +/** + 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 +RedfishConfigDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ); +#endif diff --git a/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.inf b/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.inf new file mode 100644 index 00000000000..34dc40b882a --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.inf @@ -0,0 +1,66 @@ +## @file +# INF file for the UEFI driver model Redfish Configuration Handler +# Driver. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001000b + BASE_NAME = RedfishConfigHandlerDriver + FILE_GUID = 6e881000-5749-11e8-9bf0-8cdcd426c973 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + #ENTRY_POINT = RedfishConfigHandlerDriverEntryPoint + ENTRY_POINT = _MainEntryPointDxe + IMAGE_ENTRY_POINT = _cdeCRT0UefiDxeEDK + UNLOAD_IMAGE = RedfishConfigHandlerDriverUnload + +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64 +# + +[Packages] + CdePkg/CdePkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + NetworkPkg/NetworkPkg.dec + RedfishPkg/RedfishPkg.dec + +[Sources] + RedfishConfigHandlerDriver.h + RedfishConfigHandlerDriver.c + RedfishConfigHandlerCommon.h + RedfishConfigHandlerCommon.c + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + UefiLib + MemoryAllocationLib + NetLib + UefiBootServicesTableLib + UefiDriverEntryPoint + CdeLib + +[Protocols] + gEfiRedfishDiscoverProtocolGuid ## CONSUMES + gEfiRestExServiceBindingProtocolGuid + gEfiRestExProtocolGuid ## CONSUMES + gEdkIIRedfishCredentialProtocolGuid ## CONSUMES + gEdkIIRedfishConfigHandlerProtocolGuid ## CONSUMES + +[Guids] + gEfiEventExitBootServicesGuid ## CONSUMES ## Event + gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event + +[Depex] + TRUE + AND gCdeDxeProtocolGuid +#[BuildOptions] +# MSFT:*_*_*_CC_FLAGS = /GL- /wd4189 \ No newline at end of file diff --git a/CdeEmuPkg/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.c b/CdeEmuPkg/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.c new file mode 100644 index 00000000000..2bb4bad7d49 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.c @@ -0,0 +1,229 @@ +/** @file + RedfishCrentialDxe produces the EdkIIRedfishCredentialProtocol for the consumer + to get the Redfish credential Info and to restrict Redfish access from UEFI side. + + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include // Standard C header file from CdePkg\Include\VS2022 +#include // Standard C header file from CdePkg\Include\VS2022 + +EDKII_REDFISH_CREDENTIAL_PROTOCOL mRedfishCredentialProtocol = { + RedfishCredentialGetAuthInfo, + RedfishCredentialStopService +}; + +/** + Callback function executed when the ExitBootServices event group is signaled. + + @param[in] Event Event whose notification function is being invoked. + @param[out] Context Pointer to the buffer pass in. +**/ +VOID +EFIAPI +RedfishCredentialExitBootServicesEventNotify ( + IN EFI_EVENT Event, + OUT VOID *Context + ) +{ + LibCredentialExitBootServicesNotify ((EDKII_REDFISH_CREDENTIAL_PROTOCOL *)Context); +} + +/** + Callback function executed when the EndOfDxe event group is signaled. + + @param[in] Event Event whose notification function is being invoked. + @param[out] Context Pointer to the buffer pass in. +**/ +VOID +EFIAPI +RedfishCredentialEndOfDxeEventNotify ( + IN EFI_EVENT Event, + OUT VOID *Context + ) +{ + LibCredentialEndOfDxeNotify ((EDKII_REDFISH_CREDENTIAL_PROTOCOL *)Context); + + // + // Close event, so it will not be invoked again. + // + gBS->CloseEvent (Event); +} + +/** + Retrieve platform's Redfish authentication information. + + This functions returns the Redfish authentication method together with the user Id and + password. + - For AuthMethodNone, the UserId and Password could be used for HTTP header authentication + as defined by RFC7235. + - For AuthMethodRedfishSession, the UserId and Password could be used for Redfish + session login as defined by Redfish API specification (DSP0266). + + Callers are responsible for and freeing the returned string storage. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + @param[out] AuthMethod Type of Redfish authentication method. + @param[out] UserId The pointer to store the returned UserId string. + @param[out] Password The pointer to store the returned Password string. + + @retval EFI_SUCCESS Get the authentication information successfully. + @retval EFI_ACCESS_DENIED SecureBoot is disabled after EndOfDxe. + @retval EFI_INVALID_PARAMETER This or AuthMethod or UserId or Password is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough memory resources. + @retval EFI_UNSUPPORTED Unsupported authentication method is found. + +**/ +EFI_STATUS +EFIAPI +RedfishCredentialGetAuthInfo ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, + OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod, + OUT CHAR8 **UserId, + OUT CHAR8 **Password + ) +{ + if (This == NULL || AuthMethod == NULL || UserId == NULL || Password == NULL) { + return EFI_INVALID_PARAMETER; + } + + return LibCredentialGetAuthInfo (This, AuthMethod, UserId,Password); +} + +/** + Notify the Redfish service provide to stop provide configuration service to this platform. + + This function should be called when the platfrom is about to leave the safe environment. + It will notify the Redfish service provider to abort all logined session, and prohibit + further login with original auth info. GetAuthInfo() will return EFI_UNSUPPORTED once this + function is returned. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + @param[in] ServiceStopType Reason of stopping Redfish service. + + @retval EFI_SUCCESS Service has been stoped successfully. + @retval EFI_INVALID_PARAMETER This is NULL or given the worng ServiceStopType. + @retval EFI_UNSUPPORTED Not support to stop Redfish service. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishCredentialStopService ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, + IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType + ) +{ + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + return LibStopRedfishService (This, ServiceStopType); +} + +/** + Main entry for this driver. + + @param ImageHandle Image handle this driver. + @param SystemTable Pointer to SystemTable. + + @retval EFI_SUCCESS This function always complete successfully. + +**/ +//EFI_STATUS +//EFIAPI +//RedfishCredentialDxeDriverEntryPoint ( +// IN EFI_HANDLE ImageHandle, +// IN EFI_SYSTEM_TABLE *SystemTable +// ) +EFI_STATUS main(int argc, char** argv) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + EFI_EVENT EndOfDxeEvent; + EFI_EVENT ExitBootServiceEvent; + // + // CdePkg demo + // + EFI_HANDLE ImageHandle = (void*)argv[-2]; // get ImageHandle from CdePkg backdoor + IN EFI_SYSTEM_TABLE* SystemTable = (void*)argv[-1]; // get SystemTable from CdePkg backdoor + if (1) { + extern CHAR8* gEfiCallerBaseName; + int i; + + for (i = 0; i < argc; i++) // search upcase "/DEBUGBREAK" in arguments + if (0 == strcmp("/DEBUGBREAK", argv[i])) + __debugbreak(); + + for (i = 0; i < argc; i++) + printf("### CdePkg demo ### gEfiCallerBaseName: \"%s\" argv[%d] %s\n", gEfiCallerBaseName, i, argv[i]); + + } + Handle = NULL; + + // + // Install the RedfishCredentialProtocol onto Handle. + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEdkIIRedfishCredentialProtocolGuid, + &mRedfishCredentialProtocol, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // After EndOfDxe, if SecureBoot is disabled, Redfish Credential Protocol should return + // error code to caller to avoid the 3rd code to bypass Redfish Credential Protocol and + // retrieve userid/pwd directly. So, here, we create EndOfDxe Event to check SecureBoot + // status. + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + RedfishCredentialEndOfDxeEventNotify, + (VOID *)&mRedfishCredentialProtocol, + &gEfiEndOfDxeEventGroupGuid, + &EndOfDxeEvent + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + // + // After ExitBootServices, Redfish Credential Protocol should stop the service. + // So, here, we create ExitBootService Event to stop service. + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + RedfishCredentialExitBootServicesEventNotify, + (VOID *)&mRedfishCredentialProtocol, + &gEfiEventExitBootServicesGuid, + &ExitBootServiceEvent + ); + if (EFI_ERROR (Status)) { + gBS->CloseEvent (EndOfDxeEvent); + goto ON_ERROR; + } + + return EFI_SUCCESS; + +ON_ERROR: + + gBS->UninstallMultipleProtocolInterfaces ( + Handle, + &gEdkIIRedfishCredentialProtocolGuid, + &mRedfishCredentialProtocol, + NULL + ); + + return Status; +} diff --git a/CdeEmuPkg/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.h b/CdeEmuPkg/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.h new file mode 100644 index 00000000000..aee5c67ffb7 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.h @@ -0,0 +1,75 @@ +/** @file + Definition of Redfish Credential DXE driver. + + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#ifndef EDKII_REDFISH_CREDENTIAL_DXE_H_ +#define EDKII_REDFISH_CREDENTIAL_DXE_H_ + +#include + +#include +#include +#include +#include +#include +#include + +/** + Retrieve platform's Redfish authentication information. + + This functions returns the Redfish authentication method together with the user Id and + password. + - For AuthMethodNone, the UserId and Password could be used for HTTP header authentication + as defined by RFC7235. + - For AuthMethodRedfishSession, the UserId and Password could be used for Redfish + session login as defined by Redfish API specification (DSP0266). + + Callers are responsible for and freeing the returned string storage. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + @param[out] AuthMethod Type of Redfish authentication method. + @param[out] UserId The pointer to store the returned UserId string. + @param[out] Password The pointer to store the returned Password string. + + @retval EFI_SUCCESS Get the authentication information successfully. + @retval EFI_ACCESS_DENIED SecureBoot is disabled after EndOfDxe. + @retval EFI_INVALID_PARAMETER This or AuthMethod or UserId or Password is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough memory resources. + @retval EFI_UNSUPPORTED Unsupported authentication method is found. + +**/ +EFI_STATUS +EFIAPI +RedfishCredentialGetAuthInfo ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, + OUT EDKII_REDFISH_AUTH_METHOD *AuthMethod, + OUT CHAR8 **UserId, + OUT CHAR8 **Password + ); + +/** + Notify the Redfish service provide to stop provide configuration service to this platform. + + This function should be called when the platfrom is about to leave the safe environment. + It will notify the Redfish service provider to abort all logined session, and prohibit + further login with original auth info. GetAuthInfo() will return EFI_UNSUPPORTED once this + function is returned. + + @param[in] This Pointer to EDKII_REDFISH_CREDENTIAL_PROTOCOL instance. + + @retval EFI_SUCCESS Service has been stoped successfully. + @retval EFI_INVALID_PARAMETER This is NULL. + @retval Others Some error happened. + +**/ +EFI_STATUS +EFIAPI +RedfishCredentialStopService ( + IN EDKII_REDFISH_CREDENTIAL_PROTOCOL *This, + IN EDKII_REDFISH_CREDENTIAL_STOP_SERVICE_TYPE ServiceStopType + ); +#endif diff --git a/CdeEmuPkg/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf b/CdeEmuPkg/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf new file mode 100644 index 00000000000..04360133a8f --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf @@ -0,0 +1,59 @@ +## @file +# RedfishCredentialDxe is required to produce the +# EdkII RedfishCredentialProtocol for the consumer to get the Redfish +# credential Info and to restrict Redfish access from UEFI side. +# +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001000b + BASE_NAME = RedfishCredentialDxe + FILE_GUID = 458CE95A-4942-09A9-5D21-A6B16D5DAD7F + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + #ENTRY_POINT = RedfishCredentialDxeDriverEntryPoint + ENTRY_POINT = _MainEntryPointDxe + IMAGE_ENTRY_POINT = _cdeCRT0UefiDxeEDK + +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64 +# + +[Sources] + RedfishCredentialDxe.c + RedfishCredentialDxe.h + +[Packages] + CdePkg/CdePkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + PrintLib + RedfishPlatformCredentialLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeServicesTableLib + UefiLib + CdeLib + +[Protocols] + gEdkIIRedfishCredentialProtocolGuid ## BY_START + + +[Guids] + gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event + gEfiEventExitBootServicesGuid ## CONSUMES ## Event + +[Depex] + TRUE + AND gCdeDxeProtocolGuid + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /GL- /wd4189 \ No newline at end of file diff --git a/CdeEmuPkg/RedfishPkg/RedfishDefines.dsc.inc b/CdeEmuPkg/RedfishPkg/RedfishDefines.dsc.inc new file mode 100644 index 00000000000..29a826b726f --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishDefines.dsc.inc @@ -0,0 +1,27 @@ +## @file +# RedfishPkg DSC include file for [Defines] section of all Architectures. +# +# This file can be included to the [Defines] section of a platform DSC file by +# using "!include RedfishPkg/RedfishDefines.dsc.inc" to set value of +# flags. +# +# These flags can be defined before the !include line, or changed on the command +# line to enable or disable related feature support. +# -D FLAG=VALUE +# +# The default value of these flags are: +# DEFINE REDFISH_ENABLE = TRUE +# +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +!ifndef REDFISH_ENABLE + # + # This flag is to enable or disable the whole Redfish support. + # + DEFINE REDFISH_ENABLE = TRUE +!endif + diff --git a/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/ComponentName.c b/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/ComponentName.c new file mode 100644 index 00000000000..932d668bd4d --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/ComponentName.c @@ -0,0 +1,218 @@ +/** @file + Implementation of EFI_COMPONENT_NAME_PROTOCOL and EFI_COMPONENT_NAME2_PROTOCOL protocol. + for EFI Refish Discover Protocol + + (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "RedfishDiscoverInternal.h" + +// +// EFI Component Name Functions +// +/** + Retrieves a Unicode string that is the user-readable name of the EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] Language A pointer to a three-character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param[out] DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +RedfishDiscoverComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param[in] ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param[in] Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param[out] ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language, from the point of view of the driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +RedfishDiscoverComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + + +/// +/// Component Name Protocol instance +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_COMPONENT_NAME_PROTOCOL gRedfishDiscoverComponentName = { + RedfishDiscoverComponentNameGetDriverName, + RedfishDiscoverComponentNameGetControllerName, + "eng" +}; + +/// +/// Component Name 2 Protocol instance +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_COMPONENT_NAME2_PROTOCOL gRedfishDiscoverComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) RedfishDiscoverComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) RedfishDiscoverComponentNameGetControllerName, + "en" +}; + +/// +/// Table of driver names +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_UNICODE_STRING_TABLE mRedfishDiscoverDriverNameTable[] = { + { "eng;en", (CHAR16 *)L"Redfish Discover UEFI Driver" }, + { NULL, NULL } +}; + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gRedfishDiscoverControllerNameTable = NULL; + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] Language A pointer to a three-character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param[out] DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +RedfishDiscoverComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mRedfishDiscoverDriverNameTable, + DriverName, + (BOOLEAN)(This == &gRedfishDiscoverComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param[in] ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param[in] Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param[out] ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language, from the point of view of the driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +RedfishDiscoverComponentNameGetControllerName ( + 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/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c b/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c new file mode 100644 index 00000000000..7cfe61bb648 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c @@ -0,0 +1,1931 @@ +/** @file + + The implementation of EFI Redfidh Discover Protocol. + + (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "RedfishDiscoverInternal.h" + +#include +#include + +LIST_ENTRY mRedfishDiscoverList; +LIST_ENTRY mRedfishInstanceList; +EFI_SMBIOS_PROTOCOL *mSmbios = NULL; + +UINTN mNumNetworkInterface = 0; +UINTN mNumRestExInstance = 0; +LIST_ENTRY mEfiRedfishDiscoverNetworkInterface; +LIST_ENTRY mEfiRedfishDiscoverRestExInstance; + +EFI_GUID mRedfishDiscoverTcp4InstanceGuid = EFI_REDFISH_DISCOVER_TCP4_INSTANCE_GUID; +EFI_GUID mRedfishDiscoverTcp6InstanceGuid = EFI_REDFISH_DISCOVER_TCP6_INSTANCE_GUID; +EFI_GUID mRedfishDiscoverRestExInstanceGuid = EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_GUID; + +EFI_HANDLE EfiRedfishDiscoverProtocolHandle = NULL; + +EFI_STATUS +EFIAPI +Tcp4GetSubnetInfo ( + IN EFI_HANDLE ImageHandle, + IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance +); + +EFI_STATUS +EFIAPI +Tcp6GetSubnetInfo ( + IN EFI_HANDLE ImageHandle, + IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance +); + +static REDFISH_DISCOVER_REQUIRED_PROTOCOL gRequiredProtocol[] = { + { + ProtocolTypeTcp4, + L"TCP4 Service Binding Protocol", + &gEfiTcp4ProtocolGuid, + &gEfiTcp4ServiceBindingProtocolGuid, + &mRedfishDiscoverTcp4InstanceGuid, + Tcp4GetSubnetInfo + }, + { + ProtocolTypeTcp6, + L"TCP6 Service Binding Protocol", + &gEfiTcp6ProtocolGuid, + &gEfiTcp6ServiceBindingProtocolGuid, + &mRedfishDiscoverTcp6InstanceGuid, + Tcp6GetSubnetInfo + }, + { + ProtocolTypeRestEx, + L"REST EX Service Binding Protocol", + &gEfiRestExProtocolGuid, + &gEfiRestExServiceBindingProtocolGuid, + &mRedfishDiscoverRestExInstanceGuid, + NULL + } +}; + +/** + This function creates REST EX instance for the found Resfish service. + by known owner handle. + + @param[in] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE + @param[in] Token Client token. + + @retval NULL Instance not found. + @retval EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE The instance owned by this owner. + +**/ +EFI_STATUS +CreateRestExInstance ( + IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance, + IN EFI_REDFISH_DISCOVERED_TOKEN *Token + ) +{ + EFI_STATUS Status; + + Status = RestExLibCreateChild ( + Instance->Owner, + FixedPcdGetBool (PcdRedfishDiscoverAccessModeInBand)? EfiRestExServiceInBandAccess: EfiRestExServiceOutOfBandAccess, + EfiRestExConfigHttp, + EfiRestExServiceRedfish, + &Token->DiscoverList.RedfishInstances->Information.RedfishRestExHandle + ); + return Status; +} + +/** + This function gets EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE + by known owner handle. + + @param[in] ImageHandle Image handle owns EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE. + @param[in] TargetNetworkInterface Target network interface used by this EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE. + @param[in] DiscoverFlags EFI_REDFISH_DISCOVER_FLAG + + @retval NULL Instance not found. + @retval EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE The instance owned by this owner. + +**/ +EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE * +GetInstanceByOwner ( + IN EFI_HANDLE ImageHandle, + IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *TargetNetworkInterface, + IN EFI_REDFISH_DISCOVER_FLAG DiscoverFlags + ) +{ + EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *ThisInstance; + + if (IsListEmpty (&mRedfishDiscoverList)) { + return NULL; + } + ThisInstance = + (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)GetFirstNode (&mRedfishDiscoverList); + while (TRUE) { + if ((ThisInstance->Owner == ImageHandle) && + (ThisInstance->DiscoverFlags == DiscoverFlags) && + (ThisInstance->NetworkInterface == TargetNetworkInterface)) { + return ThisInstance; + } + if (IsNodeAtEnd (&mRedfishDiscoverList, &ThisInstance->Entry)) { + break; + } + ThisInstance = + (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)GetNextNode (&mRedfishDiscoverList, &ThisInstance->Entry); + }; + return NULL; +} + +/** + This function gets the subnet information of this TCP4 instance. + + @param[in] ImageHandle EFI handle with this image. + @param[in] Instance Instance of Network interface. + @retval EFI_STATUS Get subnet information successfully. + @retval Otherwise Fail to get subnet information. +**/ +EFI_STATUS +EFIAPI +Tcp4GetSubnetInfo ( + IN EFI_HANDLE ImageHandle, + IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance +) +{ + EFI_STATUS Status; + EFI_TCP4_PROTOCOL *Tcp4; + EFI_TCP4_CONFIG_DATA Tcp4CfgData; + EFI_TCP4_OPTION Tcp4Option; + EFI_IP4_MODE_DATA IpModedata; + UINT8 SubnetMaskIndex; + UINT8 BitMask; + UINT8 PrefixLength; + BOOLEAN GotPrefixLength; + + if (Instance == NULL) { + return EFI_INVALID_PARAMETER; + } + Tcp4 = (EFI_TCP4_PROTOCOL *)Instance->NetworkInterfaceProtocolInfo.NetworkProtocolInterface; + + ZeroMem ((VOID *)&Tcp4CfgData, sizeof (EFI_TCP4_CONFIG_DATA)); + ZeroMem ((VOID *)&Tcp4Option, sizeof (EFI_TCP4_OPTION)); + // Give a local host IP address just for getting subnet information. + Tcp4CfgData.AccessPoint.UseDefaultAddress = TRUE; + Tcp4CfgData.AccessPoint.RemoteAddress.Addr [0] = 127; + Tcp4CfgData.AccessPoint.RemoteAddress.Addr [1] = 0; + Tcp4CfgData.AccessPoint.RemoteAddress.Addr [2] = 0; + Tcp4CfgData.AccessPoint.RemoteAddress.Addr [3] = 1; + Tcp4CfgData.AccessPoint.RemotePort = 80; + Tcp4CfgData.AccessPoint.ActiveFlag = TRUE; + + Tcp4CfgData.ControlOption = &Tcp4Option; + Tcp4Option.ReceiveBufferSize = 65535; + Tcp4Option.SendBufferSize = 65535; + Tcp4Option.MaxSynBackLog = 5; + Tcp4Option.ConnectionTimeout = 60; + Tcp4Option.DataRetries = 12; + Tcp4Option.FinTimeout = 2; + Tcp4Option.KeepAliveProbes = 6; + Tcp4Option.KeepAliveTime = 7200; + Tcp4Option.KeepAliveInterval = 30; + Tcp4Option.EnableNagle = TRUE; + Status = Tcp4->Configure (Tcp4, &Tcp4CfgData); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Can't get subnet information\n", __FUNCTION__)); + return Status; + } + Status = Tcp4->GetModeData (Tcp4, NULL, NULL, &IpModedata, NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Can't get IP mode data information\n", __FUNCTION__)); + return Status; + } + IP4_COPY_ADDRESS (&Instance->SubnetMask, &IpModedata.ConfigData.SubnetMask); + Instance->SubnetAddr.v4.Addr [0] = IpModedata.ConfigData.StationAddress.Addr [0] & Instance->SubnetMask.v4.Addr [0]; + Instance->SubnetAddr.v4.Addr [1] = IpModedata.ConfigData.StationAddress.Addr [1] & Instance->SubnetMask.v4.Addr [1]; + Instance->SubnetAddr.v4.Addr [2] = IpModedata.ConfigData.StationAddress.Addr [2] & Instance->SubnetMask.v4.Addr [2]; + Instance->SubnetAddr.v4.Addr [3] = IpModedata.ConfigData.StationAddress.Addr [3] & Instance->SubnetMask.v4.Addr [3]; + // + // Calculate the subnet mask prefix. + // + GotPrefixLength = FALSE; + PrefixLength = 0; + SubnetMaskIndex = 0; + while (GotPrefixLength == FALSE && SubnetMaskIndex < 4) { + BitMask = 0x80; + while (BitMask != 0) { + if ((Instance->SubnetMask.v4.Addr [SubnetMaskIndex] & BitMask) != 0) { + PrefixLength ++; + } else { + GotPrefixLength = TRUE; + break; + } + BitMask = BitMask >> 1; + }; + SubnetMaskIndex ++; + }; + Instance->SubnetPrefixLength = PrefixLength; + return EFI_SUCCESS; +} + +/** + This function gets the subnet information of this TCP6 instance. + + @param[in] ImageHandle EFI handle with this image. + @param[in] Instance Instance of Network interface. + @retval EFI_STATUS Get subnet information successfully. + @retval Otherwise Fail to get subnet information. +**/ +EFI_STATUS +EFIAPI +Tcp6GetSubnetInfo ( + IN EFI_HANDLE ImageHandle, + IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance +) +{ + EFI_STATUS Status; + EFI_TCP6_PROTOCOL *Tcp6; + EFI_IP6_MODE_DATA IpModedata; + + if (Instance == NULL) { + return EFI_INVALID_PARAMETER; + } + Tcp6 = (EFI_TCP6_PROTOCOL *)Instance->NetworkInterfaceProtocolInfo.NetworkProtocolInterface; + + Status = Tcp6->GetModeData (Tcp6, NULL, NULL, &IpModedata, NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Can't get IP mode data information\n")); + return Status; + } + if (IpModedata.AddressCount == 0) { + DEBUG ((DEBUG_INFO, "%a: No IPv6 address configured.\n")); + } + if (Instance->SubnetAddrInfoIPv6 != NULL) { + FreePool (Instance->SubnetAddrInfoIPv6); + } + Instance->SubnetAddrInfoIPv6 = AllocateZeroPool (IpModedata.AddressCount * sizeof (EFI_IP6_ADDRESS_INFO)); + if (Instance->SubnetAddrInfoIPv6 == NULL) { + DEBUG ((DEBUG_ERROR, "%a: Failed to allocate memory fir IPv6 subnet address information\n")); + return EFI_OUT_OF_RESOURCES; + } + Instance->SubnetAddrInfoIPv6Number = IpModedata.AddressCount; + CopyMem ( + (VOID *)Instance->SubnetAddrInfoIPv6, + (VOID *)&IpModedata.AddressList, + IpModedata.AddressCount * sizeof (EFI_IP6_ADDRESS_INFO) + ); + FreePool (IpModedata.AddressList); + return EFI_SUCCESS; +} + +/** + This function searches EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL + instance with the given EFI_REDFISH_DISCOVER_NETWORK_INTERFACE. + + @param[in] TargetNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE. + NULL for all EFI_REDFISH_DISCOVER_NETWORK_INTERFACEs. + + @retval Non-NULL EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL is returned. + @retval NULL Non of EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance is returned. +**/ +EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL * +GetTargetNetworkInterfaceInternal ( + IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface + ) +{ + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface; + + ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface); + while (TRUE) { + if (CompareMem((VOID *)&ThisNetworkInterface->MacAddress, &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize) == 0) { + return ThisNetworkInterface; + } + if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) { + return NULL; + } + ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode(&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry); + }; + return NULL; +} + +/** + This function validate if target network interface is ready for discovering + Redfish service. + + @param[in] TargetNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE. + NULL for all EFI_REDFISH_DISCOVER_NETWORK_INTERFACEs. + @param[in] Flags EFI_REDFISH_DISCOVER_FLAG + + @retval EFI_SUCCESS Target network interface is ready to use. + @retval EFI_UNSUPPORTED Target network interface is not ready to use. +**/ +EFI_STATUS +ValidateTargetNetworkInterface ( + IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface, + IN EFI_REDFISH_DISCOVER_FLAG Flags + ) +{ + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface; + + if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface) && TargetNetworkInterface == NULL) { + return EFI_UNSUPPORTED; + } + if (TargetNetworkInterface == NULL) { + return EFI_SUCCESS; // Return EFI_SUCCESS if no network interface is specified. + } + + ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode(&mEfiRedfishDiscoverNetworkInterface); + while (TRUE) { + if (CompareMem((VOID *)&ThisNetworkInterface->MacAddress, &TargetNetworkInterface->MacAddress, ThisNetworkInterface->HwAddressSize) == 0) { + break; + } + if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) { + return EFI_UNSUPPORTED; + } + ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode(&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry); + }; + if ((Flags & EFI_REDFISH_DISCOVER_SSDP) != 0) { + // Validate if UDP4/6 is supported on the given network interface. + // SSDP is not supported. + + return EFI_SUCCESS; + } + if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == NULL) { + return EFI_UNSUPPORTED; // The required protocol on this network interface is not found. + } + return EFI_SUCCESS; +} +/** + This function returns number of network interface instance. + + @retval UINTN Number of network interface instances. +**/ +UINTN +NumberOfNetworkInterface (VOID) +{ + UINTN Num; + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface; + + if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) { + return 0; + } + + Num = 1; + ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface); + while (TRUE) { + if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) { + break; + } + ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode(&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry); + Num ++; + }; + return Num; +} + +/** + This function checks the IP version supported on this + netwoek interface. + + @param[in] ThisNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL + + @retval TRUE Is IPv6, otherwise IPv4. + +**/ +BOOLEAN +CheckIsIpVersion6 ( + IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface +) +{ + if (ThisNetworkInterface->NetworkProtocolType == ProtocolTypeTcp6) { + return TRUE; + } + return FALSE; +} + +/** + This function discover Redfish service through SMBIOS host interface. + + @param[in] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE + + @retval EFI_SUCCESS Redfish service is discovered through SMBIOS Host interface. + @retval Others Fail to discover Redfish service throught SMBIOS host interface + +**/ +EFI_STATUS +DiscoverRedfishHostInterface (IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance) +{ + EFI_STATUS Status; + REDFISH_OVER_IP_PROTOCOL_DATA *Data; + REDFISH_INTERFACE_DATA *DeviceDescriptor; + CHAR8 UuidStr[sizeof"00000000-0000-0000-0000-000000000000" + 1]; + CHAR16 Ipv6Str [sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + 1]; + CHAR8 RedfishServiceLocateStr [sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" + 1]; + UINTN StrSize; + UINTN MacCompareStstus; + BOOLEAN IsHttps; + + Data = NULL; + DeviceDescriptor = NULL; + + if (mSmbios == NULL) { + Status = gBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, (VOID **)&mSmbios); + if (EFI_ERROR (Status)) { + return Status; + } + } + Status = RedfishGetHostInterfaceProtocolData (mSmbios, &DeviceDescriptor, &Data); // Search for SMBIOS type 42h + if (!EFI_ERROR (Status) && Data != NULL && DeviceDescriptor != NULL) { + // + // Chceck if we can reach out Redfish service using this network interface. + // Check with MAC address using Device Descroptor Data Device Type 04 and Type 05. + // Those two types of Redfish host interface device has MAC information. + // + if (DeviceDescriptor->DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) { + MacCompareStstus = CompareMem(&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.PciPcieDeviceV2.MacAddress, 6); + } else if (DeviceDescriptor->DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2){ + MacCompareStstus = CompareMem(&Instance->NetworkInterface->MacAddress, &DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.MacAddress, 6); + } else { + return EFI_UNSUPPORTED; + } + if (MacCompareStstus != 0) { + return EFI_UNSUPPORTED; + } + + if (Data->RedfishServiceIpAddressFormat == 1) { + IP4_COPY_ADDRESS ((VOID *)&Instance->TargetIpAddress.v4, (VOID *)Data->RedfishServiceIpAddress); + } else { + IP6_COPY_ADDRESS ((VOID *)&Instance->TargetIpAddress.v6, (VOID *)Data->RedfishServiceIpAddress); + } + + if (Instance->HostIntfValidation) { + DEBUG ((DEBUG_ERROR,"%a:Send UPnP unicast SSDP to validate this Redfish Host Interface is not supported.\n", __FUNCTION__)); + Status = EFI_UNSUPPORTED; + } else { + // + // Add this istance to list without detial information of Redfish + // service. + // + IsHttps = FALSE; + if (Data->RedfishServiceIpPort == 443) { + IsHttps = TRUE; + } + StrSize = sizeof(UuidStr); + AsciiSPrint(UuidStr, StrSize, "%g", &Data->ServiceUuid); + // + // Generate Redfish service location string. + // + if (Data->RedfishServiceIpAddressFormat == REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP6) { + NetLibIp6ToStr((IPv6_ADDRESS *)&Data->RedfishServiceIpAddress, Ipv6Str, sizeof (Ipv6Str)); + if (Data->RedfishServiceIpPort == 0 || IsHttps == TRUE) { + AsciiSPrintUnicodeFormat ( + RedfishServiceLocateStr, + sizeof (RedfishServiceLocateStr), + L"%s", + Ipv6Str + ); + } else { + AsciiSPrintUnicodeFormat( + RedfishServiceLocateStr, + sizeof (RedfishServiceLocateStr), + L"[%s]:%d", + Ipv6Str, + Data->RedfishServiceIpPort + ); + } + } else { + if (Data->RedfishServiceIpPort == 0 || IsHttps == TRUE) { + AsciiSPrint( + RedfishServiceLocateStr, + sizeof (RedfishServiceLocateStr), + "%d.%d.%d.%d", + Data->RedfishServiceIpAddress [0], + Data->RedfishServiceIpAddress [1], + Data->RedfishServiceIpAddress [2], + Data->RedfishServiceIpAddress [3] + ); + } else { + AsciiSPrint( + RedfishServiceLocateStr, + sizeof (RedfishServiceLocateStr), + "%d.%d.%d.%d:%d", + Data->RedfishServiceIpAddress [0], + Data->RedfishServiceIpAddress [1], + Data->RedfishServiceIpAddress [2], + Data->RedfishServiceIpAddress [3], + Data->RedfishServiceIpPort + ); + } + } + Status = AddAndSignalNewRedfishService ( + Instance, + NULL, + RedfishServiceLocateStr, + UuidStr, + NULL, + NULL, + NULL, + NULL, + IsHttps + ); + } + } + return Status; +} + +/** + The function adds a new found Redfish service to internal list and + notify client. + + @param[in] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE. + @param[in] RedfishVersion Redfish version. + @param[in] RedfishLocation Redfish location. + @param[in] Uuid Service UUID string. + @param[in] Os OS string. + @param[in] OsVer OS version string. + @param[in] Product Product string. + @param[in] ProductVer Product verison string. + @param[in] UseHttps Redfish service requires secured connection. + @retval EFI_SUCCESS Redfish service is added to list successfully. + +**/ +EFI_STATUS +AddAndSignalNewRedfishService ( + IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance, + IN UINTN *RedfishVersion OPTIONAL, + IN CHAR8 *RedfishLocation OPTIONAL, + IN CHAR8 *Uuid OPTIONAL, + IN CHAR8 *Os OPTIONAL, + IN CHAR8 *OsVer OPTIONAL, + IN CHAR8 *Product OPTIONAL, + IN CHAR8 *ProductVer OPTIONAL, + IN BOOLEAN UseHttps + ) +{ + BOOLEAN NewFound; + BOOLEAN InfoRefresh; + BOOLEAN RestExOpened; + BOOLEAN DeleteRestEx; + EFI_STATUS Status; + EFI_REDFISH_DISCOVERED_INTERNAL_LIST *DiscoveredList; + EFI_REDFISH_DISCOVERED_INSTANCE *DiscoveredInstance; + CHAR16 *Char16Uuid; + EFI_REST_EX_PROTOCOL *RestEx; + EFI_REST_EX_HTTP_CONFIG_DATA *RestExHttpConfigData; + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NetworkInterface; + + NewFound = TRUE; + InfoRefresh = FALSE; + Char16Uuid = NULL; + RestExOpened = FALSE; + DeleteRestEx = FALSE; + + DEBUG ((DEBUG_INFO,"%a:Add this instance to Redfish instance list.\n", __FUNCTION__)); + + if (Uuid != NULL) { + Char16Uuid = (CHAR16 *)AllocateZeroPool(AsciiStrSize((const CHAR8 *)Uuid) * sizeof(CHAR16)); + AsciiStrToUnicodeStrS ((const CHAR8 *)Uuid, Char16Uuid, AsciiStrSize((const CHAR8 *)Uuid) * sizeof(CHAR16)); + } + DiscoveredList = NULL; + DiscoveredInstance = NULL; + RestExHttpConfigData = NULL; + + NetworkInterface = Instance->NetworkInterface; + if (!IsListEmpty (&mRedfishInstanceList)) { + // + // Is this a duplicate redfish service. + // + DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetFirstNode (&mRedfishInstanceList); + NewFound = FALSE; + do { + if (Char16Uuid == NULL || DiscoveredList->Instance->Information.Uuid == NULL) { + // + // Check if this Redfish instance already found using IP addrress. + // + if (!CheckIsIpVersion6(NetworkInterface)) { + if (CompareMem ((VOID *)&Instance->TargetIpAddress.v4, + (VOID *)&DiscoveredList->Instance->Information.RedfishHostIpAddress.v4, + sizeof (EFI_IPv4_ADDRESS) + ) == 0) + { + DiscoveredInstance = DiscoveredList->Instance; + if (DiscoveredList->Instance->Information.Uuid == NULL && + Char16Uuid != NULL) { + InfoRefresh = TRUE; + DiscoveredInstance = DiscoveredList->Instance; + DEBUG((DEBUG_INFO,"*** This Redfish Service information refresh ***\n")); + } + break; + } + } else { + if (CompareMem ((VOID *)&Instance->TargetIpAddress.v6, + (VOID *)&DiscoveredList->Instance->Information.RedfishHostIpAddress.v6, + sizeof (EFI_IPv6_ADDRESS) + ) == 0) + { + DiscoveredInstance = DiscoveredList->Instance; + break; + } + } + } else { + // + // Check if this Redfish instance already found using UUID. + // + if (StrCmp((const CHAR16 *)Char16Uuid, (const CHAR16 *)DiscoveredList->Instance->Information.Uuid) == 0) { + DiscoveredInstance = DiscoveredList->Instance; + break; + } + } + if (IsNodeAtEnd (&mRedfishInstanceList, &DiscoveredList->NextInstance)) { + NewFound = TRUE; + break; + } + DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetNextNode (&mRedfishInstanceList, &DiscoveredList->NextInstance); + } while (TRUE); + } + if (NewFound || InfoRefresh) { + if (!InfoRefresh) { + DiscoveredList = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)AllocateZeroPool(sizeof(EFI_REDFISH_DISCOVERED_INTERNAL_LIST)); + if (DiscoveredList == NULL) { + return EFI_OUT_OF_RESOURCES; + } + InitializeListHead (&DiscoveredList->NextInstance); + DiscoveredInstance = (EFI_REDFISH_DISCOVERED_INSTANCE *)AllocateZeroPool(sizeof(EFI_REDFISH_DISCOVERED_INSTANCE)); + if (DiscoveredInstance == NULL) { + FreePool ((VOID *)DiscoveredList); + return EFI_OUT_OF_RESOURCES; + } + } + DEBUG ((DEBUG_INFO,"*** Redfish Service Information ***\n")); + + DiscoveredInstance->Information.UseHttps = UseHttps; + if (RedfishVersion != NULL) { + DiscoveredInstance->Information.RedfishVersion = *RedfishVersion; + DEBUG ((DEBUG_INFO,"Redfish service version: %d.\n", DiscoveredInstance->Information.RedfishVersion)); + } + if (RedfishLocation != NULL) { + DiscoveredInstance->Information.Location = (CHAR16 *)AllocatePool(AsciiStrSize((const CHAR8 *)RedfishLocation) * sizeof(CHAR16)); + AsciiStrToUnicodeStrS ((const CHAR8 *)RedfishLocation, DiscoveredInstance->Information.Location, AsciiStrSize((const CHAR8 *)RedfishLocation) * sizeof(CHAR16)); + DEBUG ((DEBUG_INFO,"Redfish service location: %s.\n", DiscoveredInstance->Information.Location)); + } + if (Uuid != NULL) { + DiscoveredInstance->Information.Uuid = (CHAR16 *)AllocatePool(AsciiStrSize((const CHAR8 *)Uuid) * sizeof(CHAR16)); + AsciiStrToUnicodeStrS ((const CHAR8 *)Uuid, DiscoveredInstance->Information.Uuid, AsciiStrSize((const CHAR8 *)Uuid) * sizeof(CHAR16)); + DEBUG ((DEBUG_INFO,"Service UUID: %s.\n", DiscoveredInstance->Information.Uuid)); + } + if (Os != NULL) { + DiscoveredInstance->Information.Os = (CHAR16 *)AllocatePool(AsciiStrSize((const CHAR8 *)Os) * sizeof(CHAR16)); + AsciiStrToUnicodeStrS ((const CHAR8 *)Os, DiscoveredInstance->Information.Os, AsciiStrSize((const CHAR8 *)Os) * sizeof(CHAR16)); + DEBUG ((DEBUG_INFO,"Redfish service OS: %s, Version:%s.\n", DiscoveredInstance->Information.Os, DiscoveredInstance->Information.OsVersion)); + } + if (OsVer != NULL) { + DiscoveredInstance->Information.OsVersion = (CHAR16 *)AllocatePool(AsciiStrSize((const CHAR8 *)OsVer) * sizeof(CHAR16)); + AsciiStrToUnicodeStrS ((const CHAR8 *)OsVer, DiscoveredInstance->Information.OsVersion, AsciiStrSize((const CHAR8 *)OsVer) * sizeof(CHAR16)); + } + if (Product != NULL && ProductVer != NULL) { + DiscoveredInstance->Information.Product = (CHAR16 *)AllocatePool(AsciiStrSize((const CHAR8 *)Product) * sizeof(CHAR16)); + AsciiStrToUnicodeStrS ((const CHAR8 *)Product, DiscoveredInstance->Information.Product, AsciiStrSize((const CHAR8 *)Product) * sizeof(CHAR16)); + DiscoveredInstance->Information.ProductVer = (CHAR16 *)AllocatePool(AsciiStrSize((const CHAR8 *)ProductVer) * sizeof(CHAR16)); + AsciiStrToUnicodeStrS ((const CHAR8 *)ProductVer, DiscoveredInstance->Information.ProductVer, AsciiStrSize((const CHAR8 *)ProductVer) * sizeof(CHAR16)); + DEBUG ((DEBUG_INFO,"Redfish service product: %s, Version:%s.\n", DiscoveredInstance->Information.Product, DiscoveredInstance->Information.ProductVer)); + } + + if (RedfishLocation == NULL) { + // This is the Redfish reported from SMBIOS 42h + // without validation. + + IP4_COPY_ADDRESS((VOID *)&DiscoveredInstance->Information.RedfishHostIpAddress.v4, (VOID *)&Instance->TargetIpAddress.v4); + } + if (!InfoRefresh) { + DiscoveredList->Instance = DiscoveredInstance; + InsertTailList(&mRedfishInstanceList, &DiscoveredList->NextInstance); + } + DiscoveredInstance->Status = EFI_SUCCESS; + } else { + if (DiscoveredList != NULL) { + DEBUG((DEBUG_INFO,"*** This Redfish Service was already found ***\n")); + if (DiscoveredInstance->Information.Uuid != NULL) { + DEBUG((DEBUG_INFO,"Service UUID: %s.\n", DiscoveredInstance->Information.Uuid)); + } else { + DEBUG((DEBUG_INFO,"Service UUID: unknown.\n")); + } + } + } + if (Char16Uuid != NULL) { + FreePool((VOID *)Char16Uuid); + } + + Status = EFI_SUCCESS; + if (NewFound || InfoRefresh) { + // + // Build up EFI_REDFISH_DISCOVERED_LIST in token. + // + Instance->DiscoverToken->DiscoverList.NumberOfServiceFound = 1; + Instance->DiscoverToken->DiscoverList.RedfishInstances = DiscoveredInstance; + DiscoveredInstance->Status = EFI_SUCCESS; + if (!InfoRefresh) { + Status = CreateRestExInstance (Instance, Instance->DiscoverToken); // Create REST EX child. + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a:Can't create REST EX child instance.\n",__FUNCTION__)); + goto ON_EXIT; + } + Status = gBS->OpenProtocol ( // Configure local host information. + Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle, + &gEfiRestExProtocolGuid, + (VOID **)&RestEx, + Instance->NetworkInterface->OpenDriverAgentHandle, + Instance->NetworkInterface->OpenDriverControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + DeleteRestEx = TRUE; + goto ERROR_EXIT; + } + RestExOpened = TRUE; + RestExHttpConfigData = AllocateZeroPool (sizeof (EFI_REST_EX_HTTP_CONFIG_DATA)); + if (RestExHttpConfigData == NULL) { + Status = EFI_OUT_OF_RESOURCES; + DeleteRestEx = TRUE; + goto EXIT_FREE_CONFIG_DATA; + } + RestExHttpConfigData->SendReceiveTimeout = 5000; + RestExHttpConfigData->HttpConfigData.HttpVersion = HttpVersion11; + RestExHttpConfigData->HttpConfigData.LocalAddressIsIPv6 = CheckIsIpVersion6(NetworkInterface); + if (RestExHttpConfigData->HttpConfigData.LocalAddressIsIPv6) { + RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node = AllocateZeroPool (sizeof (EFI_HTTPv6_ACCESS_POINT)); + if (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv6Node == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto EXIT_FREE_CONFIG_DATA; + } + } else { + RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node = AllocateZeroPool (sizeof (EFI_HTTPv4_ACCESS_POINT)); + if (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto EXIT_FREE_CONFIG_DATA; + } + RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node->UseDefaultAddress = TRUE; + } + Status = RestEx->Configure ( + RestEx, + (EFI_REST_EX_CONFIG_DATA)(UINT8 *)RestExHttpConfigData + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR,"%a:REST EX configured..\n", __FUNCTION__)); + DeleteRestEx = TRUE; + goto EXIT_FREE_ALL; + } + // + // Signal client, close REST EX before signaling client. + // + if (RestExOpened) { + gBS->CloseProtocol( + Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle, + &gEfiRestExProtocolGuid, + Instance->NetworkInterface->OpenDriverAgentHandle, + Instance->NetworkInterface->OpenDriverControllerHandle + ); + RestExOpened = FALSE; + } + } + Status = gBS->SignalEvent(Instance->DiscoverToken->Event); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR,"%a:No event to signal!\n", __FUNCTION__)); + } + } + +EXIT_FREE_ALL:; + if (RestExHttpConfigData != NULL && RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node != NULL) { + FreePool (RestExHttpConfigData->HttpConfigData.AccessPoint.IPv4Node); + } + +EXIT_FREE_CONFIG_DATA:; + if (RestExHttpConfigData != NULL) { + FreePool((VOID *)RestExHttpConfigData); + } + if (RestExOpened) { + gBS->CloseProtocol( + Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle, + &gEfiRestExProtocolGuid, + Instance->NetworkInterface->OpenDriverAgentHandle, + Instance->NetworkInterface->OpenDriverControllerHandle + ); + } +ERROR_EXIT:; + if (DeleteRestEx && RestExOpened) { + gBS->CloseProtocol( + Instance->DiscoverToken->DiscoverList.RedfishInstances->Information.RedfishRestExHandle, + &gEfiRestExProtocolGuid, + Instance->NetworkInterface->OpenDriverAgentHandle, + Instance->NetworkInterface->OpenDriverControllerHandle + ); + } +ON_EXIT:; + return Status; +} + +/** + This function gets the subnet information of this network interface instance. + can discover Redfish service on it. + + @param[in] Instance EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance. + @param[in] ImageHandle EFI Image handle request the network interface list. + + @retval EFI_SUCCESS + +**/ +EFI_STATUS +NetworkInterfaceGetSubnetInfo ( + IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance, + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + UINT32 ProtocolType; + UINT32 IPv6InfoIndex; + EFI_IP6_ADDRESS_INFO *ThisSubnetAddrInfoIPv6; + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NewNetworkInterface; + + if (Instance->GotSubnetInfo) { + return EFI_SUCCESS; + } + + ProtocolType = Instance->NetworkProtocolType; + if (gRequiredProtocol [ProtocolType].GetSubnetInfo != NULL && Instance->GotSubnetInfo == FALSE) { + Status = gRequiredProtocol [ProtocolType].GetSubnetInfo ( + ImageHandle, + Instance + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR,"%a:Faile to get Subnet infomation.\n", __FUNCTION__)); + return Status; + } else { + DEBUG ((DEBUG_INFO,"%a:MAC address: %s\n", __FUNCTION__, Instance->StrMacAddr)); + if (CheckIsIpVersion6 (Instance)) { + if (Instance->SubnetAddrInfoIPv6Number == 0) { + DEBUG ((DEBUG_ERROR,"%a: There is no Subnet infomation for IPv6 network interface.\n", __FUNCTION__)); + return EFI_NOT_FOUND; + } + ThisSubnetAddrInfoIPv6 = Instance->SubnetAddrInfoIPv6; // First IPv6 address information. + IP6_COPY_ADDRESS (&Instance->SubnetAddr.v6, &ThisSubnetAddrInfoIPv6->Address); + Instance->SubnetPrefixLength = ThisSubnetAddrInfoIPv6->PrefixLength; + DEBUG((DEBUG_INFO," IPv6 Subnet ID:%d, Prefix length: %d.\n", + ThisSubnetAddrInfoIPv6->Address.Addr [7] + (UINT16)ThisSubnetAddrInfoIPv6->Address.Addr [6] * 256, + ThisSubnetAddrInfoIPv6->PrefixLength) + ); + // + // If this is IPv6, then we may have to propagate network interface for IPv6 network scopes + // according to the Ipv6 address information. + // + ThisSubnetAddrInfoIPv6 ++; + for (IPv6InfoIndex = 0; IPv6InfoIndex < Instance->SubnetAddrInfoIPv6Number - 1; IPv6InfoIndex++) { + // + // Build up addtional EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instances. + // + NewNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL)); + if (NewNetworkInterface != NULL) { + CopyMem ((VOID *)NewNetworkInterface, (VOID *)Instance, sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL)); // Clone information of first instance. + IP6_COPY_ADDRESS (&NewNetworkInterface->SubnetAddr.v6, &ThisSubnetAddrInfoIPv6->Address); + NewNetworkInterface->SubnetPrefixLength = ThisSubnetAddrInfoIPv6->PrefixLength; + NewNetworkInterface->GotSubnetInfo = TRUE; + InsertTailList (&mEfiRedfishDiscoverNetworkInterface, &NewNetworkInterface->Entry); + ThisSubnetAddrInfoIPv6 ++; + mNumNetworkInterface ++; + DEBUG((DEBUG_INFO," IPv6 Subnet ID:%d, Prefix length: %d.\n", + ThisSubnetAddrInfoIPv6->Address.Addr [7] + (UINT16)ThisSubnetAddrInfoIPv6->Address.Addr [6] * 256, + ThisSubnetAddrInfoIPv6->PrefixLength) + ); + } else { + return EFI_OUT_OF_RESOURCES; + } + } + } else { + DEBUG ((DEBUG_INFO," IPv4 Subnet:%d.%d.%d.%d Subnet mask: %d.%d.%d.%d.\n", + Instance->SubnetAddr.v4.Addr [0], + Instance->SubnetAddr.v4.Addr [1], + Instance->SubnetAddr.v4.Addr [2], + Instance->SubnetAddr.v4.Addr [3], + Instance->SubnetMask.v4.Addr [0], + Instance->SubnetMask.v4.Addr [1], + Instance->SubnetMask.v4.Addr [2], + Instance->SubnetMask.v4.Addr [3] + )); + } + } + } + Instance->GotSubnetInfo = TRUE; // Only try to get Subnet Info once. + return EFI_SUCCESS; +} + +/** + This function gets the network interface list which Redfish discover protocol + can discover Redfish service on it. + + @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance. + @param[in] ImageHandle EFI Image handle request the network interface list, + @param[out] NumberOfNetworkIntfs Number of network interfaces can do Redfish service discovery. + @param[out] NetworkIntfInstances Network interface instances. It's an array of instance. The number of entries + in array is indicated by NumberOfNetworkIntfs. + Caller has to release the memory + allocated by Redfish discover protocol. + + @retval EFI_SUCCESS The information of network interface is returned in NumberOfNetworkIntfs and + NetworkIntfInstances. + @retval Others Fail to return the information of network interface. + +**/ +EFI_STATUS +EFIAPI +RedfishServiceGetNetworkInterface ( + IN EFI_REDFISH_DISCOVER_PROTOCOL *This, + IN EFI_HANDLE ImageHandle, + OUT UINTN *NumberOfNetworkIntfs, + OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE **NetworkIntfInstances +) +{ + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterfaceIntn; + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *ThisNetworkInterface; + + if (NetworkIntfInstances == NULL || NumberOfNetworkIntfs == NULL || ImageHandle == NULL) { + return EFI_INVALID_PARAMETER; + } + + *NumberOfNetworkIntfs = 0; + *NetworkIntfInstances = NULL; + + if (IsListEmpty ((const LIST_ENTRY*)&mEfiRedfishDiscoverNetworkInterface)) { + return EFI_NOT_FOUND; + } + + ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE) * mNumNetworkInterface); + if (ThisNetworkInterface == NULL) { + return EFI_OUT_OF_RESOURCES; + } + *NetworkIntfInstances = ThisNetworkInterface; + ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface); + while (TRUE) { + ThisNetworkInterface->IsIpv6 = FALSE; + if (CheckIsIpVersion6 (ThisNetworkInterfaceIntn)) { + ThisNetworkInterface->IsIpv6 = TRUE; + } + CopyMem((VOID *)&ThisNetworkInterface->MacAddress, &ThisNetworkInterfaceIntn->MacAddress, ThisNetworkInterfaceIntn->HwAddressSize); + NetworkInterfaceGetSubnetInfo(ThisNetworkInterfaceIntn, ImageHandle); // Get subnet info. + if (!ThisNetworkInterface->IsIpv6) { + IP4_COPY_ADDRESS(&ThisNetworkInterface->SubnetId.v4, &ThisNetworkInterfaceIntn->SubnetAddr.v4); // IPv4 subnet information. + } else { + IP6_COPY_ADDRESS (&ThisNetworkInterface->SubnetId.v6, &ThisNetworkInterfaceIntn->SubnetAddr.v6); // IPv6 subnet information in IPv6 address information. + } + ThisNetworkInterface->SubnetPrefixLength = ThisNetworkInterfaceIntn->SubnetPrefixLength; + ThisNetworkInterface->VlanId = ThisNetworkInterfaceIntn->VlanId; + (*NumberOfNetworkIntfs) ++; + if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry)) { + break; + } + ThisNetworkInterfaceIntn = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode(&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterfaceIntn->Entry); + ThisNetworkInterface ++; + }; + return EFI_SUCCESS; +} +/** + This function acquires Redfish services by discovering static Redfish setting + according to Redfish Host Interface or through SSDP. Returns a list of EFI + handles in EFI_REDFISH_DISCOVERED_LIST. Each of EFI handle has cooresponding + EFI REST EX instance installed on it. Each REST EX isntance is a child instance which + created through EFI REST EX serivce protoocl for communicating with specific + Redfish service. + + @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance. + @param[in] ImageHandle EFI image owns these Redfish service instances. + @param[in] TargetNetworkInterface Target network interface to do the discovery. + NULL means discover Redfish service on all network interfaces on platform. + @param[in] Flags Redfish service discover flags. + @param[in] Token EFI_REDFISH_DISCOVERED_TOKEN instance. + The memory of EFI_REDFISH_DISCOVERED_LIST and the strings in + EFI_REDFISH_DISCOVERED_INFORMATION are all allocated by Acquire() + and must be freed when caller invoke Release(). + + @retval EFI_SUCCESS REST EX instance of discovered Redfish services are returned. + @retval EFI_INVALID_PARAMETERS ImageHandle == NULL, Flags == 0, Token == NULL, Token->Timeout > 5, + or Token->Event == NULL. + @retval Others Fail acquire Redfish services. + +**/ +EFI_STATUS +EFIAPI +RedfishServiceAcquireService ( + IN EFI_REDFISH_DISCOVER_PROTOCOL *This, + IN EFI_HANDLE ImageHandle, + IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface, + IN EFI_REDFISH_DISCOVER_FLAG Flags, + IN EFI_REDFISH_DISCOVERED_TOKEN *Token + ) +{ + EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance; + EFI_STATUS Status1; + EFI_STATUS Status2; + BOOLEAN NewInstance; + UINTN NumNetworkInterfaces; + UINTN NetworkInterfacesIndex; + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *TargetNetworkInterfaceInternal; + + DEBUG ((DEBUG_INFO,"%a:Entry.\n", __FUNCTION__)); + + // + // Validate parameters. + // + if (ImageHandle == NULL || Token == NULL || ((Flags & ~EFI_REDFISH_DISCOVER_VALIDATION) == 0)) { + DEBUG ((DEBUG_ERROR,"%a:Invalid parameters.\n", __FUNCTION__)); + return EFI_INVALID_PARAMETER; + } + // + // Validate target network interface. + // + if (EFI_ERROR (ValidateTargetNetworkInterface (TargetNetworkInterface, Flags))) { + return EFI_UNSUPPORTED; + } + if (TargetNetworkInterface != NULL) { + TargetNetworkInterfaceInternal = GetTargetNetworkInterfaceInternal (TargetNetworkInterface); + NumNetworkInterfaces = 1; + } else { + TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface); + NumNetworkInterfaces = NumberOfNetworkInterface (); + if (NumNetworkInterfaces == 0) { + DEBUG ((DEBUG_ERROR,"%a:No network interface on platform.\n", __FUNCTION__)); + return EFI_UNSUPPORTED; + } + } + for (NetworkInterfacesIndex = 0; NetworkInterfacesIndex < NumNetworkInterfaces; NetworkInterfacesIndex ++) { + Status1 = EFI_SUCCESS; + Status2 = EFI_SUCCESS; + NewInstance = FALSE; + Instance = GetInstanceByOwner (ImageHandle, TargetNetworkInterfaceInternal, Flags & ~EFI_REDFISH_DISCOVER_VALIDATION); // Check if we can re-use previous instance. + if (Instance == NULL) { + DEBUG ((DEBUG_INFO,"%a:Create new EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE.\n", __FUNCTION__)); + Instance = (EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *)AllocateZeroPool(sizeof(EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE)); + if (Instance == NULL) { + DEBUG ((DEBUG_ERROR,"%a:Memory allocation fail.\n", __FUNCTION__)); + } + InitializeListHead (&Instance->Entry); + Instance->Owner = ImageHandle; + Instance->DiscoverFlags = Flags & ~EFI_REDFISH_DISCOVER_VALIDATION; + Instance->NetworkInterface = TargetNetworkInterfaceInternal; + // + // Get subnet information in case subnet information is not set because + // RedfishServiceGetNetworkInterfaces hasn't been called yet. + // + NetworkInterfaceGetSubnetInfo (TargetNetworkInterfaceInternal, ImageHandle); + NewInstance = TRUE; + } + if (TargetNetworkInterfaceInternal->StrMacAddr != NULL) { + DEBUG((DEBUG_INFO,"%a:Acquire Redfish service on network interface MAC address:%s.\n", __FUNCTION__, TargetNetworkInterfaceInternal->StrMacAddr)); + } else { + DEBUG((DEBUG_INFO,"%a:WARNING: No MAC address on this network interface.\n", __FUNCTION__)); + } + + Instance->DiscoverToken = Token; // Always use the latest Token passed by caller. + if ((Flags & EFI_REDFISH_DISCOVER_HOST_INTERFACE) != 0) { + DEBUG ((DEBUG_INFO,"%a:Redfish HOST interface discovery.\n", __FUNCTION__)); + Instance->HostIntfValidation = FALSE; + if ((Flags & EFI_REDFISH_DISCOVER_VALIDATION) != 0) { + Instance->HostIntfValidation = TRUE; + } + Status1 = DiscoverRedfishHostInterface (Instance); // Discover Redfish service through Redfish Host Interface. + } + if ((Flags & EFI_REDFISH_DISCOVER_SSDP) != 0) { + DEBUG ((DEBUG_ERROR,"%a:Redfish service discovery through SSDP is not supported\n", __FUNCTION__)); + return EFI_UNSUPPORTED; + } else { + if (EFI_ERROR (Status1) && EFI_ERROR (Status2)) { + FreePool ((VOID *)Instance); + DEBUG ((DEBUG_ERROR,"%a:Something wrong on Redfish service discovery Status1=%x, Status2=%x.\n", __FUNCTION__, Status1, Status2)); + } else { + if (NewInstance) { + InsertTailList(&mRedfishDiscoverList, &Instance->Entry); + } + } + } + if (TargetNetworkInterface == NULL) { + // + // Discover Redfish services on all of network interfaces. + // + TargetNetworkInterfaceInternal = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode(&mEfiRedfishDiscoverNetworkInterface, &TargetNetworkInterfaceInternal->Entry); + } + } + return EFI_SUCCESS; +} + +/** + This function aborts Redfish service discovery on the given network interface. + + @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance. + @param[in] TargetNetworkInterface Target network interface to do the discovery. + + @retval EFI_SUCCESS REST EX instance of discovered Redfish services are returned. + @retval Others Fail to abort Redfish service discovery. + +**/ +EFI_STATUS +EFIAPI +RedfishServiceAbortAcquire ( + IN EFI_REDFISH_DISCOVER_PROTOCOL *This, + IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *TargetNetworkInterface OPTIONAL +) +{ + // This function is used to abort Redfish service discovery through SSDP + // on the network interface. SSDP is optionally supprted by EFI_REDFISH_DISCOVER_PROTOCOL, + // we dont have implementation for SSDP now. + + return EFI_UNSUPPORTED; +} + +/** + This function releases Redfish services found by RedfishServiceAcquire(). + + @param[in] This EFI_REDFISH_DISCOVER_PROTOCOL instance. + @param[in] InstanceList The Redfish service to release. + + @retval EFI_SUCCESS REST EX instances of discovered Redfish are released. + @retval Others Fail to remove the entry + +**/ +EFI_STATUS +EFIAPI +RedfishServiceReleaseService ( + IN EFI_REDFISH_DISCOVER_PROTOCOL *This, + IN EFI_REDFISH_DISCOVERED_LIST *InstanceList + ) +{ + UINTN NumService; + BOOLEAN AnyFailRelease; + EFI_REDFISH_DISCOVERED_INSTANCE *ThisRedfishInstance; + EFI_REDFISH_DISCOVERED_INTERNAL_LIST *DiscoveredRedfishInstance; + + if (IsListEmpty (&mRedfishInstanceList)) { + DEBUG ((DEBUG_ERROR,"%a:No any discovered Redfish service.\n", __FUNCTION__)); + return EFI_NOT_FOUND; + } + AnyFailRelease = FALSE; + ThisRedfishInstance = InstanceList->RedfishInstances; + for (NumService = 0; NumService < InstanceList->NumberOfServiceFound; NumService ++) { + DiscoveredRedfishInstance = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetFirstNode(&mRedfishInstanceList); + do { + if (DiscoveredRedfishInstance->Instance == ThisRedfishInstance) { + RemoveEntryList (&DiscoveredRedfishInstance->NextInstance); + if (ThisRedfishInstance->Information.Location != NULL) { + FreePool (ThisRedfishInstance->Information.Location); + } + if (ThisRedfishInstance->Information.Uuid != NULL) { + FreePool (ThisRedfishInstance->Information.Uuid); + } + if (ThisRedfishInstance->Information.Os != NULL) { + FreePool (ThisRedfishInstance->Information.Os); + } + if (ThisRedfishInstance->Information.OsVersion != NULL) { + FreePool (ThisRedfishInstance->Information.OsVersion); + } + if (ThisRedfishInstance->Information.Product != NULL) { + FreePool (ThisRedfishInstance->Information.Product); + } + if (ThisRedfishInstance->Information.ProductVer != NULL) { + FreePool (ThisRedfishInstance->Information.ProductVer); + } + FreePool((VOID *)ThisRedfishInstance); + goto ReleaseNext; + } + + if (IsNodeAtEnd(&mRedfishInstanceList, &DiscoveredRedfishInstance->NextInstance)) { + break; + } + DiscoveredRedfishInstance = (EFI_REDFISH_DISCOVERED_INTERNAL_LIST *)GetNextNode(&mRedfishInstanceList, &DiscoveredRedfishInstance->NextInstance); + } while (TRUE); + AnyFailRelease = TRUE; +ReleaseNext:; + // + // Release next discovered Redfish Service. + // + ThisRedfishInstance = (EFI_REDFISH_DISCOVERED_INSTANCE *)((UINT8 *)ThisRedfishInstance + sizeof (EFI_REDFISH_DISCOVERED_INSTANCE)); + } + if (AnyFailRelease) { + return EFI_NOT_FOUND; + } else { + return EFI_SUCCESS; + } +} + +EFI_REDFISH_DISCOVER_PROTOCOL mRedfishDiscover = { + RedfishServiceGetNetworkInterface, + RedfishServiceAcquireService, + RedfishServiceAbortAcquire, + RedfishServiceReleaseService +}; + +/** + This function create an EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL for the + given network interface. + + + @param[in] ControllerHandle MAC address of this network interface. + @param[in] NetworkProtocolType Network protocol type. + @param[out] IsNewInstance BOOLEAN means new instance or not. + @param[out] NetworkInterface Pointer to to EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL. + + @retval EFI_STATUS +**/ +EFI_STATUS +CreateRedfishDiscoverNetworkInterface ( + IN EFI_HANDLE ControllerHandle, + IN UINT32 NetworkProtocolType, + OUT BOOLEAN *IsNewInstance, + OUT EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL **NetworkInterface + ) +{ + EFI_MAC_ADDRESS MacAddress; + UINTN HwAddressSize; + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface; + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NewNetworkInterface; + + NetLibGetMacAddress (ControllerHandle, &MacAddress, &HwAddressSize); + NewNetworkInterface = NULL; + *IsNewInstance = TRUE; + if (!IsListEmpty ((const LIST_ENTRY*)&mEfiRedfishDiscoverNetworkInterface)) { + // + // Check if this instance already exist. + // + ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface); + if (ThisNetworkInterface != NULL) { + while (TRUE) { + if ((CompareMem ((CONST VOID *)&ThisNetworkInterface->MacAddress.Addr, (CONST VOID *)&MacAddress.Addr, HwAddressSize) == 0) && + (ThisNetworkInterface->NetworkProtocolType == NetworkProtocolType)){ + NewNetworkInterface = ThisNetworkInterface; + *IsNewInstance = FALSE; + break; + } + if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) { + NewNetworkInterface = NULL; + break; + } + ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode(&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry); + }; + } + } + if (NewNetworkInterface == NULL) { + // + // Create a new instance. + // + NewNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL)); + if (NewNetworkInterface == NULL) { + return EFI_OUT_OF_RESOURCES; + } + NewNetworkInterface->HwAddressSize = HwAddressSize; + CopyMem (&NewNetworkInterface->MacAddress.Addr, &MacAddress.Addr, NewNetworkInterface->HwAddressSize); + NetLibGetMacString (ControllerHandle, NULL, &NewNetworkInterface->StrMacAddr); + NewNetworkInterface->VlanId = NetLibGetVlanId (ControllerHandle); + } + *NetworkInterface = NewNetworkInterface; + return EFI_SUCCESS; +} + +/** + This function destory network interface + + + @param[in] ThisNetworkInterface EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance. + + @retval EFI_STATUS +**/ +EFI_STATUS +DestroyRedfishNetwrokInterface ( + IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface + ) +{ + EFI_STATUS Status; + + Status = gBS->UninstallProtocolInterface( + ThisNetworkInterface->OpenDriverControllerHandle, + gRequiredProtocol [ThisNetworkInterface->NetworkProtocolType].DiscoveredProtocolGuid, + &ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolDiscoverId + ); + RemoveEntryList (&ThisNetworkInterface->Entry); + mNumNetworkInterface --; + FreePool (ThisNetworkInterface); + return Status; +} + +/** + Tests to see if the required protocols are provided on the given + controller handle. + + @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. + @retval EFI_SUCCESS One of required protocol is found. + @retval EFI_UNSUPPORTED None of required protocol is found. +**/ +EFI_STATUS +TestForRequiredProtocols ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle + ) +{ + UINT32 Id; + UINTN Index; + EFI_STATUS Status; + + for (Index = 0; Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)); Index ++) { + Status = gBS->OpenProtocol ( + ControllerHandle, + gRequiredProtocol [Index].RequiredServiceBindingProtocolGuid, + NULL, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + Status = gBS->OpenProtocol ( + ControllerHandle, + gRequiredProtocol [Index].DiscoveredProtocolGuid, + (VOID **) &Id, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "%a: %s is found on this controller handle.\n", __FUNCTION__, gRequiredProtocol [Index].ProtocolName)); + return EFI_SUCCESS; + } + } + } + return EFI_UNSUPPORTED; +} + +/** + Build up network interface and create corresponding service through the given + controller handle. + + @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. + @retval EFI_SUCCESS One of required protocol is found. + @retval EFI_UNSUPPORTED None of required protocol is found. + @retval EFI_UNSUPPORTED Failed to build up network interface. +**/ +EFI_STATUS +BuildupNetworkInterface ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle + ) +{ + UINT32 Id; + UINT32 Index; + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NetworkInterface; + BOOLEAN IsNew; + EFI_STATUS Status; + VOID *TempInterface; + VOID **Interface; + UINT32 *ProtocolDiscoverIdPtr; + EFI_HANDLE OpenDriverAgentHandle; + EFI_HANDLE OpenDriverControllerHandle; + EFI_HANDLE *HandleOfProtocolInterfacePtr; + EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance; + EFI_TPL OldTpl; + BOOLEAN NewNetworkInterfaceInstalled; + + NewNetworkInterfaceInstalled = FALSE; + Index = 0; + do { + Status = gBS->OpenProtocol ( // Already in list? + ControllerHandle, + gRequiredProtocol [Index].DiscoveredProtocolGuid, + (VOID **) &Id, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + Index ++; + if (Index == (sizeof(gRequiredProtocol) / sizeof(REDFISH_DISCOVER_REQUIRED_PROTOCOL))) { + break; + } + continue; + } + + Status = gBS->OpenProtocol ( + ControllerHandle, + gRequiredProtocol [Index].RequiredServiceBindingProtocolGuid, + &TempInterface, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + Index ++; + if (Index == (sizeof(gRequiredProtocol) / sizeof(REDFISH_DISCOVER_REQUIRED_PROTOCOL))) { + break; + } + continue; + } + if (gRequiredProtocol [Index].ProtocolType != ProtocolTypeRestEx) { + OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL); + Status = CreateRedfishDiscoverNetworkInterface(ControllerHandle, gRequiredProtocol [Index].ProtocolType, &IsNew, &NetworkInterface); + if (EFI_ERROR (Status)) { + gBS->RestoreTPL (OldTpl); + return Status; + } + NetworkInterface->NetworkProtocolType = gRequiredProtocol [Index].ProtocolType; + NetworkInterface->OpenDriverAgentHandle = This->DriverBindingHandle; + NetworkInterface->OpenDriverControllerHandle = ControllerHandle; + NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolGuid = \ + *gRequiredProtocol [Index].RequiredProtocolGuid; + NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolServiceGuid = \ + *gRequiredProtocol [Index].RequiredServiceBindingProtocolGuid; + ProtocolDiscoverIdPtr = &NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolDiscoverId; + OpenDriverAgentHandle = NetworkInterface->OpenDriverAgentHandle; + OpenDriverControllerHandle = NetworkInterface->OpenDriverControllerHandle; + HandleOfProtocolInterfacePtr = &NetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle; + Interface = &NetworkInterface->NetworkInterfaceProtocolInfo.NetworkProtocolInterface; + NewNetworkInterfaceInstalled = TRUE; + if (IsNew) { + InsertTailList (&mEfiRedfishDiscoverNetworkInterface, &NetworkInterface->Entry); + mNumNetworkInterface ++; + } + gBS->RestoreTPL (OldTpl); + } else { + // Record REST_EX instance. REST_EX is created when clinet asks for Redfish service discovery. + // Redfish Service Discover protocol will match REST EX to the corresponding EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL + // when discovery. + + RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)AllocateZeroPool (sizeof (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL)); + if (RestExInstance == NULL) { + return EFI_OUT_OF_RESOURCES; + } + RestExInstance->OpenDriverAgentHandle = This->DriverBindingHandle; + RestExInstance->OpenDriverControllerHandle = ControllerHandle; + RestExInstance->RestExControllerHandle = ControllerHandle; + InitializeListHead (&RestExInstance->Entry); + InsertTailList (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry); + mNumRestExInstance ++; + ProtocolDiscoverIdPtr = &RestExInstance->RestExId; + OpenDriverAgentHandle = RestExInstance->OpenDriverAgentHandle; + OpenDriverControllerHandle = RestExInstance->OpenDriverControllerHandle; + HandleOfProtocolInterfacePtr = &RestExInstance->RestExChildHandle; + Interface = (VOID **)&RestExInstance->RestExProtocolInterface; + } + Status = gBS->InstallProtocolInterface ( + &ControllerHandle, + gRequiredProtocol [Index].DiscoveredProtocolGuid, + EFI_NATIVE_INTERFACE, + ProtocolDiscoverIdPtr + ); + if (EFI_ERROR (Status)) { + Index ++; + if (Index == (sizeof(gRequiredProtocol) / sizeof(REDFISH_DISCOVER_REQUIRED_PROTOCOL))) { + break; + } + continue; + } + // + // Create service binding child and open it BY_DRIVER. + // + Status = NetLibCreateServiceChild ( + ControllerHandle, + This->ImageHandle, + gRequiredProtocol [Index].RequiredServiceBindingProtocolGuid, + HandleOfProtocolInterfacePtr + ); + if (!EFI_ERROR (Status)) { + Status = gBS->OpenProtocol ( + *HandleOfProtocolInterfacePtr, + gRequiredProtocol [Index].RequiredProtocolGuid, + Interface, + OpenDriverAgentHandle, + OpenDriverControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (!EFI_ERROR (Status)) { + if (EfiRedfishDiscoverProtocolHandle == NULL && + (gRequiredProtocol [Index].ProtocolType == ProtocolTypeRestEx) && + !IsListEmpty (&mEfiRedfishDiscoverNetworkInterface) + ) { + // Install the fisrt Redfish Discover Protocol when EFI REST EX protcol is discovered. + // This ensures EFI REST EX is ready while EFI_REDFISH_DISCOVER_PROTOCOL consumer acquires + // Redfish serivce over network interface. + + Status = gBS->InstallProtocolInterface ( + &EfiRedfishDiscoverProtocolHandle, + &gEfiRedfishDiscoverProtocolGuid, + EFI_NATIVE_INTERFACE, + (VOID *)&mRedfishDiscover + ); + } else if (EfiRedfishDiscoverProtocolHandle != NULL && NewNetworkInterfaceInstalled) { + Status = gBS->ReinstallProtocolInterface ( + EfiRedfishDiscoverProtocolHandle, + &gEfiRedfishDiscoverProtocolGuid, + (VOID *)&mRedfishDiscover, + (VOID *)&mRedfishDiscover + ); + NewNetworkInterfaceInstalled = FALSE; + } + } + return Status; + } else { + Index ++; + if (Index == (sizeof(gRequiredProtocol) / sizeof(REDFISH_DISCOVER_REQUIRED_PROTOCOL))) { + break; + } + continue; + } + } while (Index < (sizeof(gRequiredProtocol) / sizeof(REDFISH_DISCOVER_REQUIRED_PROTOCOL))); + return EFI_UNSUPPORTED; +} +/** + Close the protocol opened for Redfish discovery. This function also destories + the network services. + + @param[in] ThisBindingProtocol 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] ThisRequiredProtocol Pointer to the instance of REDFISH_DISCOVER_REQUIRED_PROTOCOL. + @param[in] DriverAgentHandle Driver agent handle which used to open protocol earlier. + @param[in] DriverControllerHandle Driver controller handle which used to open protocol earlier. + + @retval EFI_SUCCESS Prorocol is closed successfully. + @retval Others Prorocol is closed unsuccessfully. + +**/ +EFI_STATUS +CloseProtocolService ( + IN EFI_DRIVER_BINDING_PROTOCOL *ThisBindingProtocol, + IN EFI_HANDLE ControllerHandle, + IN REDFISH_DISCOVER_REQUIRED_PROTOCOL *ThisRequiredProtocol, + IN EFI_HANDLE DriverAgentHandle, + IN EFI_HANDLE DriverControllerHandle +) +{ + EFI_STATUS Status; + + Status = gBS->CloseProtocol ( + ControllerHandle, + ThisRequiredProtocol->RequiredProtocolGuid, + DriverAgentHandle, + DriverControllerHandle + ); + if (!EFI_ERROR (Status)) { + NetLibDestroyServiceChild( + ControllerHandle, + ThisBindingProtocol->ImageHandle, + ThisRequiredProtocol->RequiredServiceBindingProtocolGuid, + ControllerHandle + ); + } + return Status; +} +/** + Stop the services on network interface. + + @param[in] ThisBindingProtocol 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. + @retval EFI_SUCCESS One of required protocol is found. + @retval Others Faile to stop the services on network interface. +**/ +EFI_STATUS +StopServiceOnNetworkInterface ( + IN EFI_DRIVER_BINDING_PROTOCOL *ThisBindingProtocol, + IN EFI_HANDLE ControllerHandle + ) +{ + UINT32 Index; + EFI_STATUS Status; + VOID *Interface; + EFI_TPL OldTpl; + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface; + EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance; + + for (Index = 0; Index < (sizeof (gRequiredProtocol) / sizeof (REDFISH_DISCOVER_REQUIRED_PROTOCOL)); Index ++) { + Status = gBS->HandleProtocol ( + ControllerHandle, + gRequiredProtocol [Index].RequiredProtocolGuid, + (VOID **)&Interface + ); + if (!EFI_ERROR (Status)) { + if (gRequiredProtocol [Index].ProtocolType != ProtocolTypeRestEx) { + if (IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) { + return EFI_NOT_FOUND; + } + OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL); + ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface); + while (TRUE) { + if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == ControllerHandle) { + + Status = CloseProtocolService ( // Close protocol and destroy service. + ThisBindingProtocol, + ControllerHandle, + &gRequiredProtocol [Index], + ThisNetworkInterface->OpenDriverAgentHandle, + ThisNetworkInterface->OpenDriverControllerHandle + ); + if (!EFI_ERROR (Status)) { + Status = DestroyRedfishNetwrokInterface (ThisNetworkInterface); + } + gBS->RestoreTPL (OldTpl); + // Reinstall Redfish Discover protocol to notify network + // interface change. + + Status = gBS->ReinstallProtocolInterface ( + EfiRedfishDiscoverProtocolHandle, + &gEfiRedfishDiscoverProtocolGuid, + (VOID *)&mRedfishDiscover, + (VOID *)&mRedfishDiscover + ); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_ERROR, "%a: Reinstall gEfiRedfishDiscoverProtocolGuid fail.", __FUNCTION__)); + } + return Status; + } + if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) { + break; + } + ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode(&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry); + }; + gBS->RestoreTPL (OldTpl); + } else { + if (IsListEmpty (&mEfiRedfishDiscoverRestExInstance)) { + return EFI_NOT_FOUND; + } + OldTpl = gBS->RaiseTPL (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL); + RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverRestExInstance); + while (TRUE) { + if (RestExInstance->RestExChildHandle == ControllerHandle) { + Status = CloseProtocolService ( // Close REST_EX protocol. + ThisBindingProtocol, + ControllerHandle, + &gRequiredProtocol [Index], + RestExInstance->OpenDriverAgentHandle, + RestExInstance->OpenDriverControllerHandle + ); + RemoveEntryList (&RestExInstance->Entry); + FreePool ((VOID *)RestExInstance); + mNumRestExInstance --; + gBS->RestoreTPL (OldTpl); + return Status; + } + if (IsNodeAtEnd (&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry)) { + break; + } + RestExInstance = (EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *)GetNextNode(&mEfiRedfishDiscoverRestExInstance, &RestExInstance->Entry); + }; + gBS->RestoreTPL (OldTpl); + } + } + } + return EFI_NOT_FOUND; +} +/** + 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 +RedfishDiscoverDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + return TestForRequiredProtocols (This, ControllerHandle); +} + +/** + 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 +RedfishDiscoverDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + return BuildupNetworkInterface (This, ControllerHandle); +} + +/** + 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 +RedfishDiscoverDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +{ + return StopServiceOnNetworkInterface (This, ControllerHandle); +} + +EFI_DRIVER_BINDING_PROTOCOL gRedfishDiscoverDriverBinding = { + RedfishDiscoverDriverBindingSupported, + RedfishDiscoverDriverBindingStart, + RedfishDiscoverDriverBindingStop, + REDFISH_DISCOVER_VERSION, + NULL, + NULL +}; + +/** + This is the declaration of an EFI image entry point. + + @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 Others An unexpected error occurred. +**/ +//EFI_STATUS +//EFIAPI +//RedfishDiscoverEntryPoint ( +// IN EFI_HANDLE ImageHandle, +// IN EFI_SYSTEM_TABLE *SystemTable +// ) +//{ +EFI_STATUS main(int argc, char** argv) +{ + EFI_HANDLE ImageHandle = (void*)argv[-2]; + IN EFI_SYSTEM_TABLE* SystemTable = (void*)argv[-1]; + EFI_STATUS Status; + // + // CdePkg demo + // + if (1) { + extern CHAR8* gEfiCallerBaseName; + int i; + + for (i = 0; i < argc; i++) // search upcase "/DEBUGBREAK" in arguments + if(0 == strcmp("/DEBUGBREAK", argv[i])) + __debugbreak(); + + for (i = 0; i < argc; i++) + printf("### CdePkg demo ### gEfiCallerBaseName: \"%s\" argv[%d] %s\n", gEfiCallerBaseName, i, argv[i]); + + } + Status = EFI_SUCCESS; + InitializeListHead (&mRedfishDiscoverList); + InitializeListHead (&mRedfishInstanceList); + InitializeListHead (&mEfiRedfishDiscoverNetworkInterface); + InitializeListHead (&mEfiRedfishDiscoverRestExInstance); + // + // Install binding protoocl to obtain UDP and REST EX protocol. + // + Status = EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gRedfishDiscoverDriverBinding, + ImageHandle, + &gRedfishDiscoverComponentName, + &gRedfishDiscoverComponentName2 + ); + return Status; +} + +/** + This is the unload handle for Redfish discover module. + + Disconnect the driver specified by ImageHandle from all the devices in the handle database. + Uninstall all the protocols installed in the driver entry point. + + @param[in] ImageHandle The drivers' driver image. + + @retval EFI_SUCCESS The image is unloaded. + @retval Others Failed to unload the image. + +**/ +EFI_STATUS +EFIAPI +RedfishDiscoverUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface; + + Status = EFI_SUCCESS; + // Destroy all network interfaces found by EFI Redfish Discover driver and + // stop services created for Redfish Discover. + + while (!IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)) { + ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface); + StopServiceOnNetworkInterface (&gRedfishDiscoverDriverBinding, ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle); + }; + // Disconnect EFI Redfish discover driver controller to notify the + // clinet which uses .EFI Redfish discover protocol. + + if (EfiRedfishDiscoverProtocolHandle != NULL) { + // + // Notify user EFI_REDFISH_DISCOVER_PROTOCOL is unloaded. + // + gBS->DisconnectController (EfiRedfishDiscoverProtocolHandle, NULL, NULL); + Status = gBS->UninstallProtocolInterface( + EfiRedfishDiscoverProtocolHandle, + &gEfiRedfishDiscoverProtocolGuid, + (VOID *)&mRedfishDiscover + ); + } + return Status; +} diff --git a/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.inf b/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.inf new file mode 100644 index 00000000000..d1a67335dcc --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.inf @@ -0,0 +1,65 @@ +## @file +# Implementation of EFI_REDFISH_DISCOVER_PROTOCOL interfaces. +# +# (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001b + BASE_NAME = RedfishDiscoverDxe + FILE_GUID = 28A76FE5-43D7-48A3-9714-C1B7BDD6DFB6 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + #ENTRY_POINT = RedfishDiscoverEntryPoint + ENTRY_POINT = _MainEntryPointDxe + IMAGE_ENTRY_POINT = _cdeCRT0UefiDxeEDK + UNLOAD_IMAGE = RedfishDiscoverUnload + +[Packages] + CdePkg/CdePkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + NetworkPkg/NetworkPkg.dec + RedfishPkg/RedfishPkg.dec + +[Sources] + ComponentName.c + RedfishDiscoverDxe.c + RedfishSmbiosHostInterface.c + RedfishDiscoverInternal.h + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + PrintLib + RestExLib + UefiLib + UefiBootServicesTableLib + UefiDriverEntryPoint + CdeLib + +[Protocols] + gEfiRestExServiceBindingProtocolGuid ## Consuming + gEfiRestExProtocolGuid ## Consuming + gEfiTcp4ServiceBindingProtocolGuid ## Consuming + gEfiTcp4ProtocolGuid ## Consuming + gEfiTcp6ServiceBindingProtocolGuid ## Consuming + gEfiTcp6ProtocolGuid ## Consuming + gEfiRedfishDiscoverProtocolGuid ## Prodcuing + gEfiSmbiosProtocolGuid ## Consuming + gEfiDriverBindingProtocolGuid ## Consuming + +[Pcd] + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDiscoverAccessModeInBand ## CONSUMES + +[Depex] + gCdeDxeProtocolGuid + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /GL- /wd4189 +# MSFT:*_*_*_DLINK_FLAGS = /verbose \ No newline at end of file diff --git a/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h b/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h new file mode 100644 index 00000000000..5407ee879d4 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h @@ -0,0 +1,234 @@ +/** @file + This file defines the EFI Redfish Discover Protocol interface. + + (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EFI_REDFISH_DISCOVER_INTERNAL_H_ +#define EFI_REDFISH_DISCOVER_INTERNAL_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define REDFISH_DISCOVER_VERSION 0x00010000 +#define EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_TPL TPL_NOTIFY + +// +//GUID definitions +// + +#define EFI_REDFISH_DISCOVER_TCP4_INSTANCE_GUID \ + { \ + 0xfbab97a4, 0x4c6a, 0xf8e8, { 0xf2, 0x25, 0x42, 0x8a, 0x80, 0x3f, 0xb6, 0xaa } \ + } + +#define EFI_REDFISH_DISCOVER_TCP6_INSTANCE_GUID \ + { \ + 0xbe513b6d, 0x41c1, 0x96Ed, { 0x8d, 0xaf, 0x3e, 0x89, 0xc5, 0xf5, 0x02, 0x25 } \ + } + +#define EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_GUID \ + { \ + 0xc44a6076, 0xd42a, 0x4d54, { 0x85, 0x6d, 0x98, 0x8a, 0x85, 0x8f, 0xa1, 0x11 } \ + } + +extern EFI_COMPONENT_NAME_PROTOCOL gRedfishDiscoverComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gRedfishDiscoverComponentName2; +extern EFI_UNICODE_STRING_TABLE *gRedfishDiscoverControllerNameTable; + +// +// Enumeration of network protocols +// required for the Redfish service discovery. +// +typedef enum { + ProtocolTypeTcp4 = 0, ///< Network protocol TCPv4. + ProtocolTypeTcp6, ///< Network protocol TCCv6. + ProtocolTypeRestEx, ///< REST EX over network protocol. + MaxProtocolType +} NETWORK_INTERFACE_PROTOCOL_TYPE; + +// +// Network protocol information installed on +// the network interface. +// +typedef struct { + EFI_GUID ProtocolGuid; ///< Network protocol GUID. + EFI_GUID ProtocolServiceGuid; ///< Network protocol service GUID. + UINT32 ProtocolDiscoverId; ///< The identifier installed on network protocol handle. + EFI_HANDLE ProtocolControllerHandle; ///< The controller handle on network protocol. + VOID *NetworkProtocolInterface; ///< The protocol interface of network protocol. +} REDFISH_DISCOVER_NETWORK_INTERFACE_PROTOCOL; + +// +// Internal structure used to maintain network +// interface properties. +// +typedef struct { + LIST_ENTRY Entry; ///< Link list entry. + EFI_HANDLE OpenDriverAgentHandle; ///< The agent to open network protocol. + EFI_HANDLE OpenDriverControllerHandle; ///< The controller handle to open network protocol. + UINTN HwAddressSize; ///< The size of network interface hardware address. + EFI_MAC_ADDRESS MacAddress; ///< MAC address of network interface. + CHAR16 *StrMacAddr; ///< String to MAC address of network interface. + BOOLEAN GotSubnetInfo; ///< Indicates sub net information is retrieved. + EFI_IP_ADDRESS SubnetAddr; ///< Subnet ID. + EFI_IP_ADDRESS SubnetMask; ///< Subnet mask (IPv4 only) + UINT8 SubnetPrefixLength; ///< Subnet prefix. + UINT16 VlanId; ///< VLAN ID + UINT32 SubnetAddrInfoIPv6Number; ///< IPv6 address info number. + EFI_IP6_ADDRESS_INFO *SubnetAddrInfoIPv6; ///< IPv6 address info. + // + // Network interface protocol and REST EX infor. + // + UINT32 NetworkProtocolType; ///< Network protocol type. Refer to + ///< NETWORK_INTERFACE_PROTOCOL_TYPE. + REDFISH_DISCOVER_NETWORK_INTERFACE_PROTOCOL NetworkInterfaceProtocolInfo; ///< Network interface protocol information. + EFI_HANDLE RestExHandle; ///< REST EX handle associated with this network interface. +} EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL; + +// +// Internal structure used to maintain REST EX properties. +// +typedef struct { + LIST_ENTRY Entry; ///< Link list entry. + EFI_HANDLE OpenDriverAgentHandle; ///< The agent to open network protocol. + EFI_HANDLE OpenDriverControllerHandle; ///< The controller handle to open network protocol. + EFI_HANDLE RestExChildHandle; ///< The child handle created throught REST EX Service Protocol. + EFI_HANDLE RestExControllerHandle; ///< The controller handle which provide REST EX protocol. + EFI_REST_EX_PROTOCOL *RestExProtocolInterface; ///< Pointer to EFI_REST_EX_PROTOCOL. + UINT32 RestExId; ///< The identifier installed on REST EX controller handle. +} EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL; + +/** + This function to get subnet information. + + @param[in] ImageHandle EFI handle with this image. + @param[in] Instance Instance of Network interface. + @retval EFI_STATUS Get subnet information successfully. + @retval Otherwise Fail to get subnet information. +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_REDFISH_DISCOVER_GET_SUBNET_INFO)( + IN EFI_HANDLE ImageHandle, + IN EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *Instance +); + +// +// The require network protocol matrix. +// +typedef struct { + UINT32 ProtocolType; ///< Network protocol type, + ///< Refer to NETWORK_INTERFACE_PROTOCOL_TYPE. + CHAR16 *ProtocolName; ///< Protocol name. + EFI_GUID *RequiredProtocolGuid; ///< Network protocol interface GUID. + EFI_GUID *RequiredServiceBindingProtocolGuid; ///< Network protocol service GUID. + EFI_GUID *DiscoveredProtocolGuid; ///< Protocol interface GUID use to install identifier. + EFI_REDFISH_DISCOVER_GET_SUBNET_INFO GetSubnetInfo; ///< Function of getting subnet information. +} REDFISH_DISCOVER_REQUIRED_PROTOCOL; + +// +// Link list of Redfish discover instance. +// +typedef struct { + LIST_ENTRY NextInstance; ///< Next list. + EFI_REDFISH_DISCOVERED_INSTANCE *Instance; ///< Pointer to EFI_REDFISH_DISCOVERED_INSTANCE. +} EFI_REDFISH_DISCOVERED_INTERNAL_LIST; + +// +// Internal structure of Redfish discover instance. +// +typedef struct { + LIST_ENTRY Entry; ///< Link list entry. + EFI_HANDLE Owner; ///< The owner owns this Redfish service discovery. + ///< It's the EFI image handle of driver uses + ///< EFI Redfish Discover Protocol. + EFI_REDFISH_DISCOVER_FLAG DiscoverFlags; ///< EFI_REDFISH_DISCOVER_FLAG + EFI_REDFISH_DISCOVERED_TOKEN *DiscoverToken; ///< Token used to signal when Redfish service is discovered. + EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *NetworkInterface; ///< EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL + ///< instance used to discover Redfish service. + // + // Below for Host insterface discovery. + // + BOOLEAN HostIntfValidation; ///< Indicates whether to validate Redfish Host interface. + EFI_IP_ADDRESS TargetIpAddress; ///< Target IP address reported in Redfish Host interface. +} EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE; + +/** + The function adds a new foudn Redfish service to internal list and + notify clinet. + + It simply frees the packet. + + @param[in] Instance EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE. + @param[in] RedfishVersion Redfish version. + @param[in] RedfishLocation Redfish location. + @param[in] Uuid Service UUID string. + @param[in] Os OS string. + @param[in] OsVer OS version string. + @param[in] Product Product string. + @param[in] ProductVer Product verison string. + @param[in] UseHttps Redfish service requires secured connection. + @retval EFI_SUCCESS Redfish service is added to list successfully. + +**/ +EFI_STATUS +AddAndSignalNewRedfishService ( + IN EFI_REDFISH_DISCOVERED_INTERNAL_INSTANCE *Instance, + IN UINTN *RedfishVersion OPTIONAL, + IN CHAR8 *RedfishLocation OPTIONAL, + IN CHAR8 *Uuid OPTIONAL, + IN CHAR8 *Os OPTIONAL, + IN CHAR8 *OsVer OPTIONAL, + IN CHAR8 *Product OPTIONAL, + IN CHAR8 *ProductVer OPTIONAL, + IN BOOLEAN UseHttps + ); + +/** + The function gets information reported in Redfish Host Interface. + + It simply frees the packet. + + @param[in] Smbios SMBIOS protocol. + @param[out] DeviceDescriptor Pointer to REDFISH_INTERFACE_DATA. + @param[out] ProtocolData Pointer to REDFISH_OVER_IP_PROTOCOL_DATA. + + @retval EFI_SUCCESS Get host interface succesfully. + @retval Otherwise Fail to tet host interface. + +**/ +EFI_STATUS +RedfishGetHostInterfaceProtocolData ( + IN EFI_SMBIOS_PROTOCOL *Smbios, + OUT REDFISH_INTERFACE_DATA **DeviceDescriptor, + OUT REDFISH_OVER_IP_PROTOCOL_DATA **ProtocolData + ); + +extern EFI_GUID gRedfishDiscoverTcp4Instance; +extern EFI_GUID gRedfishDiscoverTcp6Instance; +extern EFI_GUID gRedfishDiscoverRestEXInstance; +#endif diff --git a/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/RedfishSmbiosHostInterface.c b/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/RedfishSmbiosHostInterface.c new file mode 100644 index 00000000000..78d1447a086 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishDiscoverDxe/RedfishSmbiosHostInterface.c @@ -0,0 +1,118 @@ +/** @file + RedfishSmbiosHostInterface.c + + Discover Redfish SMBIOS Host Interface. + + (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "RedfishDiscoverInternal.h" + +SMBIOS_TABLE_TYPE42 *mType42Record; + +/** + The function gets information reported in Redfish Host Interface. + + It simply frees the packet. + + @param[in] Smbios SMBIOS protocol. + @param[out] DeviceDescriptor Pointer to REDFISH_INTERFACE_DATA. + @param[out] ProtocolData Pointer to REDFISH_OVER_IP_PROTOCOL_DATA. + + @retval EFI_SUCCESS Get host interface succesfully. + @retval Otherwise Fail to tet host interface. + +**/ +EFI_STATUS +RedfishGetHostInterfaceProtocolData ( + IN EFI_SMBIOS_PROTOCOL *Smbios, + OUT REDFISH_INTERFACE_DATA **DeviceDescriptor, + OUT REDFISH_OVER_IP_PROTOCOL_DATA **ProtocolData + ) +{ + EFI_STATUS Status; + EFI_SMBIOS_HANDLE SmbiosHandle; + EFI_SMBIOS_TABLE_HEADER *Record; + UINT16 Offset; + UINT8 *RecordTmp; + UINT8 ProtocolLength; + UINT8 SpecificDataLen; + + if ((Smbios == NULL) || (ProtocolData == NULL)) { + return EFI_INVALID_PARAMETER; + } + + SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; + Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL); + while (!EFI_ERROR (Status) && SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED) { + if (Record->Type == SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE) { + // + // Check Interface Type, should be Network Host Interface = 40h + // + mType42Record = (SMBIOS_TABLE_TYPE42 *) Record; + if (mType42Record->InterfaceType == MCHostInterfaceTypeNetworkHostInterface) { + ASSERT (Record->Length >= 9); + Offset = 5; + RecordTmp = (UINT8 *) Record + Offset; + // + // Get interface specific data length. + // + SpecificDataLen = *RecordTmp; + Offset += 1; + RecordTmp = (UINT8 *) Record + Offset; + + // + // Check Device Type, only PCI/PCIe Network Interface v2 is supported now. + // + if (*RecordTmp == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) { + ASSERT (SpecificDataLen == sizeof (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2) + 1); + *DeviceDescriptor = (REDFISH_INTERFACE_DATA *)RecordTmp; + Offset = Offset + SpecificDataLen; + RecordTmp = (UINT8 *) Record + Offset; + // + // Check Protocol count. if > 1, only use the first protocol. + // + ASSERT (*RecordTmp == 1); + Offset += 1; + RecordTmp = (UINT8 *) Record + Offset; + // + // Check protocol identifier. + // + if (*RecordTmp == MCHostInterfaceProtocolTypeRedfishOverIP) { + Offset += 1; + RecordTmp = (UINT8 *) Record + Offset; + ProtocolLength = *RecordTmp; + + Offset += 1; + RecordTmp = (UINT8 *) Record + Offset; + + // + // This SMBIOS record is invalid, if the length of protocol specific data for + // Redfish Over IP protocol is wrong. + // + if ((*(RecordTmp + 90) + sizeof (REDFISH_OVER_IP_PROTOCOL_DATA) - 1) != ProtocolLength) { + return EFI_SECURITY_VIOLATION; + } + + Offset += ProtocolLength; + // + // This SMBIOS record is invalid, if the length is smaller than the offset. + // + if (Offset > mType42Record->Hdr.Length) { + return EFI_SECURITY_VIOLATION; + } + *ProtocolData = (REDFISH_OVER_IP_PROTOCOL_DATA *)RecordTmp; + return EFI_SUCCESS; + } + } + } + } + Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL); + } + + *ProtocolData = NULL; + return EFI_NOT_FOUND; +} diff --git a/CdeEmuPkg/RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.c b/CdeEmuPkg/RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.c new file mode 100644 index 00000000000..5bcff6c92ca --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.c @@ -0,0 +1,265 @@ +/** @file + RedfishHostInterfaceDxe builds up SMBIOS Type 42h host interface + record for Redfish service host interface using EFI MBIOS Protocol. + RedfishHostInterfacePlatformLib is the platform-level library which + provides the content of Redfish host interface type 42h record. + + 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 +#include +#include + +#include +#include + +/** + Create SMBIOS type 42 record for Redfish host interface. + + @retval EFI_SUCCESS SMBIOS type 42 record is created. + @retval Others Fail to create SMBIOS 42 record. + +**/ +EFI_STATUS +RedfishCreateSmbiosTable42 ( + VOID + ) +{ + REDFISH_INTERFACE_DATA *DeviceDescriptor; + UINT8 DeviceDataLength; + UINT8 DeviceType; + EFI_STATUS Status; + MC_HOST_INTERFACE_PROTOCOL_RECORD *ProtocolRecord; + VOID *ProtocolRecords; + VOID *NewProtocolRecords; + UINT8 ProtocolCount; + UINT8 CurrentProtocolsDataLength; + UINT8 NewProtocolsDataLength; + UINT8 ProtocolDataSize; + SMBIOS_TABLE_TYPE42 *Type42Record; + EFI_SMBIOS_PROTOCOL *Smbios; + EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle; + + // + // Get platform Redfish host interface device type descriptor data. + // + Status = RedfishPlatformHostInterfaceDeviceDescriptor (&DeviceType, &DeviceDescriptor); + if (EFI_ERROR (Status)) { + if (Status == EFI_NOT_FOUND) { + DEBUG ((DEBUG_ERROR, "%a: No Redfish host interface descriptor is provided on this platform.", __FUNCTION__)); + return EFI_NOT_FOUND; + } + DEBUG((DEBUG_ERROR, "%a: Fail to get device descriptor, %r.", __FUNCTION__, Status)); + return Status; + } + if (DeviceType != REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2 && + DeviceType != REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2 + ) { + DEBUG ((DEBUG_ERROR, "%a: Only support either protocol type 04h or 05h as Redfish host interface.", __FUNCTION__)); + return EFI_UNSUPPORTED; + } + if (DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) { + DeviceDataLength = DeviceDescriptor->DeviceDescriptor.PciPcieDeviceV2.Length; + } else { + DeviceDataLength = DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.Length; + } + // + // Loop to get platform Redfish host interface protocol type data. + // + ProtocolRecord = NULL; + ProtocolRecords = NULL; + NewProtocolRecords = NULL; + Type42Record = NULL; + ProtocolCount = 0; + CurrentProtocolsDataLength = 0; + NewProtocolsDataLength = 0; + while (TRUE) { + Status = RedfishPlatformHostInterfaceProtocolData (&ProtocolRecord, ProtocolCount); + if (Status == EFI_NOT_FOUND) { + break; + } + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to get Redfish host interafce protocol type data.", __FUNCTION__)); + if (ProtocolRecords != NULL) { + FreePool (ProtocolRecords); + } + if (ProtocolRecord != NULL) { + FreePool (ProtocolRecord); + } + return Status; + } + ProtocolDataSize = sizeof (MC_HOST_INTERFACE_PROTOCOL_RECORD) - sizeof(ProtocolRecord->ProtocolTypeData) + ProtocolRecord->ProtocolTypeDataLen; + NewProtocolsDataLength += ProtocolDataSize; + if (ProtocolRecords == NULL) { + ProtocolRecords = AllocateZeroPool (NewProtocolsDataLength); + if (ProtocolRecords == NULL) { + FreePool (ProtocolRecord); + return EFI_OUT_OF_RESOURCES; + } + CopyMem ((VOID *)ProtocolRecords, (VOID *)ProtocolRecord, ProtocolDataSize); + NewProtocolRecords = ProtocolRecords; + } else { + NewProtocolRecords = ReallocatePool(CurrentProtocolsDataLength, NewProtocolsDataLength, (VOID *)ProtocolRecords); + if (NewProtocolRecords == NULL) { + DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for Redfish host interface protocol data.")); + FreePool (ProtocolRecords); + FreePool (ProtocolRecord); + return EFI_OUT_OF_RESOURCES; + } + CopyMem ( + (VOID *)((UINT8 *)NewProtocolRecords + CurrentProtocolsDataLength), + (VOID *)ProtocolRecord, + ProtocolDataSize + ); + } + FreePool (ProtocolRecord); + CurrentProtocolsDataLength = NewProtocolsDataLength; + ProtocolCount ++; + }; + if (ProtocolCount == 0) { + goto ON_EXIT; + } + // + // Construct SMBIOS Type 42h for Redfish host inteface. + // + // SMBIOS type 42 Record for Redfish Interface + // 00h Type BYTE 42 Management Controller Host Interface structure indicator + // 01h Length BYTE Varies Length of the structure, a minimum of 09h + // 02h Handle WORD Varies + // 04h Interface Type BYTE Varies Management Controller Interface Type. + // 05h Interface Specific Data Length (n) + // 06h Interface Specific data + // 06h+n number of protocols defined for the host interface (typically 1) + // 07h+n Include a Protocol Record for each protocol supported. + // + Type42Record = (SMBIOS_TABLE_TYPE42 *) AllocateZeroPool ( + sizeof (SMBIOS_TABLE_TYPE42) - 4 + + DeviceDataLength + + 1 /// For Protocol Record Count + + CurrentProtocolsDataLength + + 2 /// Double NULL terminator/ + ); + if (Type42Record == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + Type42Record->Hdr.Type = EFI_SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE; + Type42Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE42) - 4 + + DeviceDataLength + + 1 + + CurrentProtocolsDataLength; + Type42Record->Hdr.Handle = 0; + Type42Record->InterfaceType = MCHostInterfaceTypeNetworkHostInterface; // Network Host Interface + + // + // Fill in InterfaceTypeSpecificDataLength field + // + Type42Record->InterfaceTypeSpecificDataLength = DeviceDataLength; + + // + // Fill in InterfaceTypeSpecificData field + // + CopyMem (Type42Record->InterfaceTypeSpecificData, DeviceDescriptor, DeviceDataLength); + FreePool (DeviceDescriptor); + DeviceDescriptor = NULL; + + // + // Fill in InterfaceTypeSpecificData Protocol Count field + // + *(Type42Record->InterfaceTypeSpecificData + DeviceDataLength) = ProtocolCount; + + // + // Fill in Redfish Protocol Data + // + CopyMem ( + Type42Record->InterfaceTypeSpecificData + DeviceDataLength + 1, + NewProtocolRecords, + CurrentProtocolsDataLength + ); + + // + // 5. Add Redfish interface data record to SMBIOS table 42 + // + Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; + Status = Smbios->Add ( + Smbios, + NULL, + &MemArrayMappedAddrSmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER*) Type42Record + ); + DEBUG ((DEBUG_INFO, "RedfishPlatformDxe: Smbios->Add() - %r\n", Status)); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + Status = EFI_SUCCESS; + +ON_EXIT: + if (DeviceDescriptor != NULL) { + FreePool (DeviceDescriptor); + } + if (NewProtocolRecords != NULL) { + FreePool (NewProtocolRecords); + } + if (Type42Record != NULL) { + FreePool (Type42Record); + } + return Status; +} + +/** + Main entry for this driver. + + @param ImageHandle Image handle this driver. + @param SystemTable Pointer to SystemTable. + + @retval EFI_SUCCESS This function always complete successfully. + +**/ +//EFI_STATUS +//EFIAPI +//RedfishHostInterfaceDxeEntryPoint ( +// IN EFI_HANDLE ImageHandle, +// IN EFI_SYSTEM_TABLE *SystemTable +// ) +//{ +EFI_STATUS main(int argc, char** argv) +{ + EFI_HANDLE ImageHandle = (void*)argv[-2]; + IN EFI_SYSTEM_TABLE* SystemTable = (void*)argv[-1]; + // + // Create SMBIOS type 42 record. + // + // + // CdePkg demo + // + if (1) { + extern CHAR8* gEfiCallerBaseName; + int i; + + for (i = 0; i < argc; i++) // search upcase "/DEBUGBREAK" in arguments + if(0 == strcmp("/DEBUGBREAK", argv[i])) + __debugbreak(); + + for (i = 0; i < argc; i++) + printf("### CdePkg demo ### gEfiCallerBaseName: \"%s\" argv[%d] %s\n", gEfiCallerBaseName, i, argv[i]); + + } + return RedfishCreateSmbiosTable42 (); +} diff --git a/CdeEmuPkg/RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf b/CdeEmuPkg/RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf new file mode 100644 index 00000000000..fc146fea31e --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf @@ -0,0 +1,57 @@ +## @file +# RedfishHostInterfaceDxe builds up SMBIOS Type 42h host interface +# record for Redfish service host interface using SMBIOS Protocol. +# RedfishHostInterfacePlatformLib is the platform-level library which +# provides the content of Redfish host interface type 42h record. +# +# 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 = RedfishHostInterfaceDxe + FILE_GUID = 592626DA-4A1E-8B39-28BA-FEAD92C4A0A4 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + #ENTRY_POINT = RedfishHostInterfaceDxeEntryPoint + ENTRY_POINT = _MainEntryPointDxe + IMAGE_ENTRY_POINT = _cdeCRT0UefiDxeEDK + +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64 +# + +[Sources] + RedfishHostInterfaceDxe.c + +[Packages] + CdePkg/CdePkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + PrintLib + RedfishPlatformHostInterfaceLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiLib + CdeLib + +[Protocols] + gEfiSmbiosProtocolGuid ## TO_START + +[Depex] + gEfiSmbiosProtocolGuid + AND gCdeDxeProtocolGuid + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /GL- /wd4189 \ No newline at end of file diff --git a/CdeEmuPkg/RedfishPkg/RedfishLibs.dsc.inc b/CdeEmuPkg/RedfishPkg/RedfishLibs.dsc.inc new file mode 100644 index 00000000000..0bcc32c32f0 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishLibs.dsc.inc @@ -0,0 +1,21 @@ +## @file +# Redfish DSC include file for [LibraryClasses*] section of all Architectures. +# +# This file can be included to the [LibraryClasses*] section(s) of a platform DSC file +# by using "!include RedfishPkg/RedfisLibs.dsc.inc" to specify the library instances +# of EDKII network library classes. +# +# (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +!if $(REDFISH_ENABLE) == TRUE + RestExLib|RedfishPkg/Library/DxeRestExLib/DxeRestExLib.inf + Ucs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf + BaseSortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf + RedfishCrtLib|RedfishPkg/PrivateLibrary/RedfishCrtLib/RedfishCrtLib.inf + JsonLib|RedfishPkg/Library/JsonLib/JsonLib.inf + RedfishLib|RedfishPkg/PrivateLibrary/RedfishLib/RedfishLib.inf +!endif + diff --git a/CdeEmuPkg/RedfishPkg/RedfishPkg.ci.yaml b/CdeEmuPkg/RedfishPkg/RedfishPkg.ci.yaml new file mode 100644 index 00000000000..887c5ad42f8 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishPkg.ci.yaml @@ -0,0 +1,105 @@ +## @file +# CI configuration for NetworkPkg +# +# (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## +{ + "LicenseCheck": { + "IgnoreFiles": [] + }, + "EccCheck": { + ## Exception sample looks like below: + ## "ExceptionList": [ + ## "", "" + ## ] + "ExceptionList": [ + ], + ## Both file path and directory path are accepted. + "IgnoreFiles": [ + ## Below are files incorporated with open source which are + ## not edk2 coding standard compliant. + ## + ## EDK2 CRT library which is not edk2 coding + ## standard compliant. + ## C runtime library for RedfishPkg modules + "PrivateInclude/Crt/sys", + "PrivateInclude/Crt/assert.h", + "PrivateInclude/Crt/errno.h", + "PrivateInclude/Crt/limits.h", + "PrivateInclude/Crt/math.h", + "PrivateInclude/Crt/stdarg.h", + "PrivateInclude/Crt/stddef.h", + "PrivateInclude/Crt/stdio.h", + "PrivateInclude/Crt/stdlib.h", + "PrivateInclude/Crt/string.h", + "PrivateInclude/Crt/time.h", + "PrivateLibrary/RedfishCrtLib/RedfishCrtLib.c", + "Include/Library/RedfishCrtLib.h", + ## + ## For jansson library open source + ## load.c is overrided from open source. + "Library/JsonLib/load.c", + "Library/JsonLib/jansson_config.h", + "Library/JsonLib/jansson_private_config.h", + ## + ## For libredfish open source + ## The files under edk2libredfish are cloned + ## from DMTF open source + "PrivateLibrary/RedfishLib/edk2libredfish/include/redfish.h", + "PrivateLibrary/RedfishLib/edk2libredfish/include/redfishPayload.h", + "PrivateLibrary/RedfishLib/edk2libredfish/include/redfishService.h", + "PrivateLibrary/RedfishLib/edk2libredfish/include/redpath.h", + "PrivateLibrary/RedfishLib/edk2libredfish/src/payload.c", + "PrivateLibrary/RedfishLib/edk2libredfish/src/redpath.c", + "PrivateLibrary/RedfishLib/edk2libredfish/src/service.c" + ] + }, + "CompilerPlugin": { + "DscPath": "RedfishPkg.dsc" + }, + "CharEncodingCheck": { + "IgnoreFiles": [] + }, + "DependencyCheck": { + "AcceptableDependencies": [ + "MdePkg/MdePkg.dec", + "MdeModulePkg/MdeModulePkg.dec", + "NetworkPkg/NetworkPkg.dec", + "RedfishPkg/RedfishPkg.dec" + ], + # For host based unit tests + "AcceptableDependencies-HOST_APPLICATION":[], + # For UEFI shell based apps + "AcceptableDependencies-UEFI_APPLICATION":[ + "ShellPkg/ShellPkg.dec" + ], + "IgnoreInf": [] + }, + "DscCompleteCheck": { + "DscPath": "RedfishPkg.dsc", + "IgnoreInf": [] + }, + "GuidCheck": { + "IgnoreGuidName": [], + "IgnoreGuidValue": [], + "IgnoreFoldersAndFiles": [] + }, + "LibraryClassCheck": { + "IgnoreHeaderFile": [] + }, + + ## options defined ci/Plugin/SpellCheck + "SpellCheck": { + "AuditOnly": True, # Fails test but run in AuditOnly mode to collect log + "IgnoreFiles": [], # use gitignore syntax to ignore errors in matching files + "ExtendWords": [], # 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) + }, + + "Defines": { + "BLD_*_CONTINUOUS_INTEGRATION": "TRUE", + "BLD_*_REDFISH_ENABLE": "TRUE" + } +} diff --git a/CdeEmuPkg/RedfishPkg/RedfishPkg.dec b/CdeEmuPkg/RedfishPkg/RedfishPkg.dec new file mode 100644 index 00000000000..7f5cb82aef0 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishPkg.dec @@ -0,0 +1,100 @@ +## @file +# Redfish Package +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# (C) Copyright 2021 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + DEC_SPECIFICATION = 0x0001001b + PACKAGE_NAME = RedfishPkg + PACKAGE_GUID = c432b76e-5232-11e7-9010-005056c00008 + PACKAGE_VERSION = 1.0 + +[Includes] + Include + +[Includes.Common.Private] + PrivateInclude # Private header files for C RTL. + PrivateInclude/Crt # Private header files for C RTL. + Library/JsonLib # Private header files for jansson + # configuration files. + # - jansson_config.h + # - jansson_private_config.h + # jansson.h refers to above two configuration + # files for building platform jansson library. + Library/JsonLib/jansson/src # For referring to jannson.h + +[LibraryClasses] + ## @libraryclass Platform Redfish Host Interface Library + # Platform implementation-specific Redfish Host Interface. + RedfishPlatformHostInterfaceLib|Include/Library/RedfishHostInterfaceLib.h + + ## @libraryclass This library provides UCS2 to UTF8 manipulation + # functions. + # + Ucs2Utf8Lib|Include/Library/BaseUcs2Utf8Lib.h + + ## @libraryclass Platform Redfish Credential Library + # Platform implementation-specific Redfish Credential Interface. + RedfishPlatformCredentialLib|Include/Library/RedfishCredentialLib.h + + ## @libraryclass The helper routines to access REST EX service. + # This library is only intended to be used by UEFI network stack modules. + RestExLib|Include/Library/RestExLib.h + + ## @libraryclass Provides the library functions based on third party + # jansson library to manipulate JSON data structure. + # + JsonLib|Include/Library/JsonLib.h + + ## @libraryclass Provides the library functions to encode/decode + # Redfish packet. + # + RedfishContentCodingLib|Include/Library/RedfishContentCodingLib.h + +[LibraryClasses.Common.Private] + ## @libraryclass Provides the private C runtime library functions. + # CRT library is currently used by edk2 JsonLib (open source + # jansson project) and edk2 RedfishLib (libredfish open source + # project). + RedfishCrtLib|Include/Library/RedfishCrtLib.h + + ## @libraryclass Redfish Helper Library + # Library provides Redfish helper functions. + RedfishLib|PrivateInclude/Library/RedfishLib.h + +[Protocols] + ## Include/Protocol/EdkIIRedfishCredential.h + gEdkIIRedfishCredentialProtocolGuid = { 0x8804377, 0xaf7a, 0x4496, { 0x8a, 0x7b, 0x17, 0x59, 0x0, 0xe9, 0xab, 0x46 } } + + ## Include/Protocol/Edk2RedfishConfigHandler.h + gEdkIIRedfishConfigHandlerProtocolGuid = { 0xbc0fe6bb, 0x2cc9, 0x463e, { 0x90, 0x82, 0xfa, 0x11, 0x76, 0xfc, 0x67, 0xde } } + +[Guids] + gEfiRedfishPkgTokenSpaceGuid = { 0x4fdbccb7, 0xe829, 0x4b4c, { 0x88, 0x87, 0xb2, 0x3f, 0xd7, 0x25, 0x4b, 0x85 }} + +[PcdsFixedAtBuild, PcdsPatchableInModule] + # + # This PCD is the UEFI device path which is used as the Redfish host interface. + # + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceDevicePath|{0x0}|REST_EX_SERVICE_DEVICE_PATH_DATA|0x00001000 { + + Pcd/RestExServiceDevicePath.h + + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + } + # + # This PCD indicates the EFI REST EX access mode to Redfish service. + # Default is set to out of band access. + # + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceAccessModeInBand|FALSE|BOOLEAN|0x00001001 + # + # This PCD indicates the access mode EFI Discover protocol uses to look for the proper EFI REST EX + # protocol instance. + # + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishDiscoverAccessModeInBand|FALSE|BOOLEAN|0x00001002 diff --git a/CdeEmuPkg/RedfishPkg/RedfishPkg.dsc b/CdeEmuPkg/RedfishPkg/RedfishPkg.dsc new file mode 100644 index 00000000000..b0d36e7f748 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishPkg.dsc @@ -0,0 +1,62 @@ +## @file +# Redfish Package +# +# Copyright (c) 2019 - 2021, Intel Corporation. All rights reserved.
+# (C) Copyright 2021 Hewlett-Packard Enterprise Development LP. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + PLATFORM_NAME = RedfishPkg + PLATFORM_GUID = c4352870-5232-11e7-9522-005056c00008 + PLATFORM_VERSION = 1.0 + DSC_SPECIFICATION = 0x0001001c + OUTPUT_DIRECTORY = Build/RedfishPkg + SUPPORTED_ARCHITECTURES = IA32|X64|ARM|AARCH64|RISCV64 + BUILD_TARGETS = DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER = DEFAULT + +!include MdePkg/MdeLibs.dsc.inc + +[LibraryClasses] + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + RedfishPlatformHostInterfaceLib|RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.inf + HttpLib|NetworkPkg/Library/DxeHttpLib/DxeHttpLib.inf + HttpIoLib|NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.inf + NetLib|NetworkPkg/Library/DxeNetLib/DxeNetLib.inf + DpcLib|NetworkPkg/Library/DxeDpcLib/DxeDpcLib.inf + RedfishPlatformCredentialLib|RedfishPkg/Library/PlatformCredentialLibNull/PlatformCredentialLibNull.inf + RedfishContentCodingLib|RedfishPkg/Library/RedfishContentCodingLibNull/RedfishContentCodingLibNull.inf + +[LibraryClasses.ARM, LibraryClasses.AARCH64] + # + # This library provides the instrinsic functions generated by a given compiler. + # + NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf + NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf + ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf + +[Components] + RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.inf + RedfishPkg/Library/PlatformCredentialLibNull/PlatformCredentialLibNull.inf + RedfishPkg/Library/RedfishContentCodingLibNull/RedfishContentCodingLibNull.inf + RedfishPkg/Library/DxeRestExLib/DxeRestExLib.inf + RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf + RedfishPkg/PrivateLibrary/RedfishCrtLib/RedfishCrtLib.inf + RedfishPkg/Library/JsonLib/JsonLib.inf + RedfishPkg/PrivateLibrary/RedfishLib/RedfishLib.inf + + !include RedfishPkg/Redfish.dsc.inc diff --git a/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/ComponentName.c b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/ComponentName.c new file mode 100644 index 00000000000..1147d0701ea --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/ComponentName.c @@ -0,0 +1,222 @@ +/** @file + Implementation of EFI_COMPONENT_NAME_PROTOCOL and EFI_COMPONENT_NAME2_PROTOCOL + protocol. + + 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 + +// +// EFI Component Name Functions +// +/** + Retrieves a Unicode string that is the user-readable name of the EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] Language A pointer to a three-character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param[out] DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param[in] ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param[in] Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param[out] ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language, from the point of view of the driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +/// +/// Component Name Protocol instance +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_COMPONENT_NAME_PROTOCOL gRedfishRestExComponentName = { + RedfishRestExComponentNameGetDriverName, + RedfishRestExComponentNameGetControllerName, + "eng" +}; + +/// +/// Component Name 2 Protocol instance +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_COMPONENT_NAME2_PROTOCOL gRedfishRestExComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) RedfishRestExComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) RedfishRestExComponentNameGetControllerName, + "en" +}; + +/// +/// Table of driver names +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_UNICODE_STRING_TABLE mRedfishRestExDriverNameTable[] = { + { "eng;en", (CHAR16 *)L"Redfish RestEx Network Service Driver" }, + { NULL, NULL } +}; + +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gRedfishRestExControllerNameTable = NULL; + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] Language A pointer to a three-character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param[out] DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mRedfishRestExDriverNameTable, + DriverName, + (BOOLEAN)(This == &gRedfishRestExComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param[in] ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param[in] ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param[in] Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param[out] ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language, from the point of view of the driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExComponentNameGetControllerName ( + 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/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c new file mode 100644 index 00000000000..f695803e45a --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c @@ -0,0 +1,853 @@ +/** @file + The driver binding and service binding protocol for Redfish RestExDxe driver. + + 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 "RedfishRestExDriver.h" + +#include +#include + +EFI_DRIVER_BINDING_PROTOCOL gRedfishRestExDriverBinding = { + RedfishRestExDriverBindingSupported, + RedfishRestExDriverBindingStart, + RedfishRestExDriverBindingStop, + REDFISH_RESTEX_DRIVER_VERSION, + NULL, + NULL +}; + +EFI_SERVICE_BINDING_PROTOCOL mRedfishRestExServiceBinding = { + RedfishRestExServiceBindingCreateChild, + RedfishRestExServiceBindingDestroyChild +}; + +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +EFIAPI +RestExDestroyChildEntryInHandleBuffer ( + IN LIST_ENTRY *Entry, + IN VOID *Context + ) +{ + RESTEX_INSTANCE *Instance; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; + + if (Entry == NULL || Context == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = NET_LIST_USER_STRUCT_S (Entry, RESTEX_INSTANCE, Link, RESTEX_INSTANCE_SIGNATURE); + ServiceBinding = ((RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding; + NumberOfChildren = ((RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren; + ChildHandleBuffer = ((RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer; + + if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) { + return EFI_SUCCESS; + } + + return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle); +} + +/** + Destroy the RestEx instance and recycle the resources. + + @param[in] Instance The pointer to the RestEx instance. + +**/ +VOID +RestExDestroyInstance ( + IN RESTEX_INSTANCE *Instance + ) +{ + HttpIoDestroyIo (&(Instance->HttpIo)); + + FreePool (Instance); +} + +/** + Create the RestEx instance and initialize it. + + @param[in] Service The pointer to the RestEx service. + @param[out] Instance The pointer to the RestEx instance. + + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. + @retval EFI_SUCCESS The RestEx instance is created. + +**/ +EFI_STATUS +RestExCreateInstance ( + IN RESTEX_SERVICE *Service, + OUT RESTEX_INSTANCE **Instance + ) +{ + RESTEX_INSTANCE *RestExIns; + EFI_STATUS Status; + + *Instance = NULL; + Status = EFI_SUCCESS; + + RestExIns = AllocateZeroPool (sizeof (RESTEX_INSTANCE)); + if (RestExIns == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + RestExIns->Signature = RESTEX_INSTANCE_SIGNATURE; + InitializeListHead (&RestExIns->Link); + RestExIns->InDestroy = FALSE; + RestExIns->Service = Service; + + CopyMem (&RestExIns->RestEx, &mRedfishRestExProtocol, sizeof (RestExIns->RestEx)); + + // + // Create a HTTP_IO to access the HTTP service. + // + Status = HttpIoCreateIo ( + RestExIns->Service->ImageHandle, + RestExIns->Service->ControllerHandle, + IP_VERSION_4, + NULL, + NULL, + NULL, + &(RestExIns->HttpIo) + ); + if (EFI_ERROR (Status)) { + FreePool (RestExIns); + return Status; + } + + *Instance = RestExIns; + + return EFI_SUCCESS; +} + +/** + Release all the resource used the RestEx service binding instance. + + @param[in] RestExSb The RestEx service binding instance. + +**/ +VOID +RestExDestroyService ( + IN RESTEX_SERVICE *RestExSb + ) +{ + if (RestExSb->HttpChildHandle != NULL) { + gBS->CloseProtocol ( + RestExSb->HttpChildHandle, + &gEfiHttpProtocolGuid, + RestExSb->ImageHandle, + RestExSb->ControllerHandle + ); + + NetLibDestroyServiceChild ( + RestExSb->ControllerHandle, + RestExSb->ImageHandle, + &gEfiHttpServiceBindingProtocolGuid, + RestExSb->HttpChildHandle + ); + + RestExSb->HttpChildHandle = NULL; + } + + gBS->UninstallProtocolInterface ( + RestExSb->ControllerHandle, + &gEfiCallerIdGuid, + &RestExSb->Id + ); + + FreePool (RestExSb); +} + +/** + Check the NIC controller handle represents an in-band or out-of-band Redfish host + interface device. If not in-band, treat it as out-of-band interface device. + + @param[in] Controller The NIC controller handle needs to be checked. + + @return EFI_REST_EX_SERVICE_ACCESS_MODE of the device. + +**/ +EFI_REST_EX_SERVICE_ACCESS_MODE +RestExServiceAccessMode ( + IN EFI_HANDLE Controller + ) +{ + // + // This is EFI REST EX driver instance to connect + // to Redfish service using HTTP in out of band. + // + if (FixedPcdGetBool (PcdRedfishRestExServiceAccessModeInBand)) { + return EfiRestExServiceInBandAccess; + } else { + return EfiRestExServiceOutOfBandAccess; + } +} + +/** + Create then initialize a RestEx service binding instance. + + @param[in] Controller The controller to install the RestEx service + binding on. + @param[in] Image The driver binding image of the RestEx driver. + @param[out] Service The variable to receive the created service + binding instance. + + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the instance. + @retval EFI_SUCCESS The service instance is created for the controller. + +**/ +EFI_STATUS +RestExCreateService ( + IN EFI_HANDLE Controller, + IN EFI_HANDLE Image, + OUT RESTEX_SERVICE **Service + ) +{ + EFI_STATUS Status; + RESTEX_SERVICE *RestExSb; + + Status = EFI_SUCCESS; + RestExSb = NULL; + + *Service = NULL; + + RestExSb = AllocateZeroPool (sizeof (RESTEX_SERVICE)); + if (RestExSb == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + RestExSb->Signature = RESTEX_SERVICE_SIGNATURE; + + RestExSb->ServiceBinding = mRedfishRestExServiceBinding; + + RestExSb->RestExChildrenNum = 0; + InitializeListHead (&RestExSb->RestExChildrenList); + + RestExSb->ControllerHandle = Controller; + RestExSb->ImageHandle = Image; + + RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.EfiRestExServiceInfoHeader.Length = sizeof (EFI_REST_EX_SERVICE_INFO); + RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.EfiRestExServiceInfoHeader.RestServiceInfoVer.Major = 1; + RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.EfiRestExServiceInfoHeader.RestServiceInfoVer.Minor = 0; + RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestServiceType = EfiRestExServiceRedfish; + RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestServiceAccessMode = RestExServiceAccessMode (Controller); + RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestExConfigType = EfiRestExConfigHttp; + RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestExConfigDataLength = sizeof (EFI_REST_EX_HTTP_CONFIG_DATA); + + Status = gBS->InstallProtocolInterface ( + &Controller, + &gEfiCallerIdGuid, + EFI_NATIVE_INTERFACE, + &RestExSb->Id + ); + if (EFI_ERROR (Status)) { + FreePool (RestExSb); + RestExSb = NULL; + } + + *Service = RestExSb; + return Status; +} + +/** + 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[in] ImageHandle The firmware allocated handle for the UEFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval Others An unexpected error occurred. +**/ +//EFI_STATUS +//EFIAPI +//RedfishRestExDriverEntryPoint ( +// IN EFI_HANDLE ImageHandle, +// IN EFI_SYSTEM_TABLE *SystemTable +// ) +EFI_STATUS main(int argc, char **argv) +{ + EFI_HANDLE ImageHandle = (void*)argv[-2]; + IN EFI_SYSTEM_TABLE *SystemTable =(void*)argv[-1]; + + EFI_STATUS Status; + // + // CdePkg demo + // + if (1) { + extern CHAR8* gEfiCallerBaseName; + int i; + + for (i = 0; i < argc; i++) // search upcase "/DEBUGBREAK" in arguments + if(0 == strcmp("/DEBUGBREAK", argv[i])) + __debugbreak(); + + for (i = 0; i < argc; i++) + printf("### CdePkg demo ### gEfiCallerBaseName: \"%s\" argv[%d] %s\n", gEfiCallerBaseName, i, argv[i]); + + } + + Status = EFI_SUCCESS; + + // + // Install the RestEx Driver Binding Protocol. + // + Status = EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gRedfishRestExDriverBinding, + ImageHandle, + &gRedfishRestExComponentName, + &gRedfishRestExComponentName2 + ); + if (EFI_ERROR (Status)) { + return Status; + } + + 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 +RedfishRestExDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + + // + // Test for the HttpServiceBinding Protocol. + // + return gBS->OpenProtocol ( + ControllerHandle, + &gEfiHttpServiceBindingProtocolGuid, + NULL, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + +} + +/** + 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 +RedfishRestExDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + RESTEX_SERVICE *RestExSb; + EFI_STATUS Status; + UINT32 *Id; + VOID *Interface; + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiCallerIdGuid, + (VOID **) &Id, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + return EFI_ALREADY_STARTED; + } + + Status = RestExCreateService (ControllerHandle, This->DriverBindingHandle, &RestExSb); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (RestExSb != NULL); + + // + // Create a Http child instance, but do not configure it. + // This will establish the parent-child relationship. + // + Status = NetLibCreateServiceChild ( + ControllerHandle, + This->DriverBindingHandle, + &gEfiHttpServiceBindingProtocolGuid, + &RestExSb->HttpChildHandle + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + Status = gBS->OpenProtocol ( + RestExSb->HttpChildHandle, + &gEfiHttpProtocolGuid, + &Interface, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + // + // Install the RestEx ServiceBinding Protocol onto ControllerHandle. + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &ControllerHandle, + &gEfiRestExServiceBindingProtocolGuid, + &RestExSb->ServiceBinding, + NULL + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + return EFI_SUCCESS; + +ON_ERROR: + RestExDestroyService (RestExSb); + + 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 +RedfishRestExDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +{ + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + RESTEX_SERVICE *RestExSb; + EFI_HANDLE NicHandle; + EFI_STATUS Status; + LIST_ENTRY *List; + RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; + + // + // RestEx driver opens HTTP child, So, Controller is a HTTP + // child handle. Locate the Nic handle first. Then get the + // RestEx private data back. + // + NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiHttpProtocolGuid); + if (NicHandle == NULL) { + return EFI_SUCCESS; + } + + Status = gBS->OpenProtocol ( + NicHandle, + &gEfiRestExServiceBindingProtocolGuid, + (VOID **) &ServiceBinding, + This->DriverBindingHandle, + NicHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + RestExSb = RESTEX_SERVICE_FROM_THIS (ServiceBinding); + + if (!IsListEmpty (&RestExSb->RestExChildrenList)) { + // + // Destroy the RestEx child instance in ChildHandleBuffer. + // + List = &RestExSb->RestExChildrenList; + Context.ServiceBinding = ServiceBinding; + Context.NumberOfChildren = NumberOfChildren; + Context.ChildHandleBuffer = ChildHandleBuffer; + Status = NetDestroyLinkList ( + List, + RestExDestroyChildEntryInHandleBuffer, + &Context, + NULL + ); + } + + if (NumberOfChildren == 0 && IsListEmpty (&RestExSb->RestExChildrenList)) { + gBS->UninstallProtocolInterface ( + NicHandle, + &gEfiRestExServiceBindingProtocolGuid, + ServiceBinding + ); + + RestExDestroyService (RestExSb); + + if (gRedfishRestExControllerNameTable != NULL) { + FreeUnicodeStringTable (gRedfishRestExControllerNameTable); + gRedfishRestExControllerNameTable = NULL; + } + + Status = EFI_SUCCESS; + } + + return Status; +} + +/** + Creates a child handle and installs a protocol. + + The CreateChild() function installs a protocol on ChildHandle. + If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle. + If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle. + + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. + @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL, + then a new handle is created. If it is a pointer to an existing UEFI handle, + then the protocol is added to the existing UEFI handle. + + @retval EFI_SUCCES The protocol was added to ChildHandle. + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create + the child + @retval other The child handle was not created + +**/ +EFI_STATUS +EFIAPI +RedfishRestExServiceBindingCreateChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE *ChildHandle + ) +{ + RESTEX_SERVICE *RestExSb; + RESTEX_INSTANCE *Instance; + EFI_STATUS Status; + EFI_TPL OldTpl; + VOID *Http; + + if ((This == NULL) || (ChildHandle == NULL)) { + return EFI_INVALID_PARAMETER; + } + + RestExSb = RESTEX_SERVICE_FROM_THIS (This); + + Status = RestExCreateInstance (RestExSb, &Instance); + if (EFI_ERROR (Status)) { + return Status; + } + ASSERT (Instance != NULL); + + // + // Install the RestEx protocol onto ChildHandle + // + Status = gBS->InstallMultipleProtocolInterfaces ( + ChildHandle, + &gEfiRestExProtocolGuid, + &Instance->RestEx, + NULL + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + Instance->ChildHandle = *ChildHandle; + + // + // Open the Http protocol BY_CHILD. + // + Status = gBS->OpenProtocol ( + RestExSb->HttpChildHandle, + &gEfiHttpProtocolGuid, + (VOID **) &Http, + gRedfishRestExDriverBinding.DriverBindingHandle, + Instance->ChildHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + gBS->UninstallMultipleProtocolInterfaces ( + Instance->ChildHandle, + &gEfiRestExProtocolGuid, + &Instance->RestEx, + NULL + ); + + goto ON_ERROR; + } + + // + // Open the Http protocol by child. + // + Status = gBS->OpenProtocol ( + Instance->HttpIo.Handle, + &gEfiHttpProtocolGuid, + (VOID **) &Http, + gRedfishRestExDriverBinding.DriverBindingHandle, + Instance->ChildHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + // + // Close the Http protocol. + // + gBS->CloseProtocol ( + RestExSb->HttpChildHandle, + &gEfiHttpProtocolGuid, + gRedfishRestExDriverBinding.DriverBindingHandle, + ChildHandle + ); + + gBS->UninstallMultipleProtocolInterfaces ( + Instance->ChildHandle, + &gEfiRestExProtocolGuid, + &Instance->RestEx, + NULL + ); + + goto ON_ERROR; + } + + // + // Add it to the parent's child list. + // + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + InsertTailList (&RestExSb->RestExChildrenList, &Instance->Link); + RestExSb->RestExChildrenNum++; + + gBS->RestoreTPL (OldTpl); + + return EFI_SUCCESS; + +ON_ERROR: + + RestExDestroyInstance (Instance); + return Status; +} + +/** + Destroys a child handle with a protocol installed on it. + + The DestroyChild() function does the opposite of CreateChild(). It removes a protocol + that was installed by CreateChild() from ChildHandle. If the removed protocol is the + last protocol on ChildHandle, then ChildHandle is destroyed. + + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. + @param[in] ChildHandle Handle of the child to destroy + + @retval EFI_SUCCES The protocol was removed from ChildHandle. + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed. + @retval EFI_INVALID_PARAMETER Child handle is NULL. + @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle + because its services are being used. + @retval other The child handle was not destroyed + +**/ +EFI_STATUS +EFIAPI +RedfishRestExServiceBindingDestroyChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE ChildHandle + ) +{ + RESTEX_SERVICE *RestExSb; + RESTEX_INSTANCE *Instance; + + EFI_REST_EX_PROTOCOL *RestEx; + EFI_STATUS Status; + EFI_TPL OldTpl; + + if ((This == NULL) || (ChildHandle == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Retrieve the private context data structures + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiRestExProtocolGuid, + (VOID **) &RestEx, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + Instance = RESTEX_INSTANCE_FROM_THIS (RestEx); + RestExSb = RESTEX_SERVICE_FROM_THIS (This); + + if (Instance->Service != RestExSb) { + return EFI_INVALID_PARAMETER; + } + + if (Instance->InDestroy) { + return EFI_SUCCESS; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Instance->InDestroy = TRUE; + + // + // Close the Http protocol. + // + gBS->CloseProtocol ( + RestExSb->HttpChildHandle, + &gEfiHttpProtocolGuid, + gRedfishRestExDriverBinding.DriverBindingHandle, + ChildHandle + ); + + gBS->CloseProtocol ( + Instance->HttpIo.Handle, + &gEfiHttpProtocolGuid, + gRedfishRestExDriverBinding.DriverBindingHandle, + ChildHandle + ); + + + gBS->RestoreTPL (OldTpl); + + // + // Uninstall the RestEx protocol first to enable a top down destruction. + // + Status = gBS->UninstallProtocolInterface ( + ChildHandle, + &gEfiRestExProtocolGuid, + RestEx + ); + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + if (EFI_ERROR (Status)) { + Instance->InDestroy = FALSE; + gBS->RestoreTPL (OldTpl); + return Status; + } + + RemoveEntryList (&Instance->Link); + RestExSb->RestExChildrenNum--; + + gBS->RestoreTPL (OldTpl); + + RestExDestroyInstance (Instance); + return EFI_SUCCESS; +} + diff --git a/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.h b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.h new file mode 100644 index 00000000000..0b9ba701bdd --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.h @@ -0,0 +1,650 @@ +/** @file + RedfishRestExDxe support functions definitions. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EFI_REDFISH_RESTEX_DRIVER_H_ +#define EFI_REDFISH_RESTEX_DRIVER_H_ + +/// +/// Libraries classes +/// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/// +/// UEFI Driver Model Protocols +/// +#include +#include +#include + +/// +/// Protocol instances +/// +extern EFI_COMPONENT_NAME_PROTOCOL gRedfishRestExComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gRedfishRestExComponentName2; +extern EFI_UNICODE_STRING_TABLE *gRedfishRestExControllerNameTable; + +extern EFI_DRIVER_BINDING_PROTOCOL gRedfishRestExDriverBinding; +extern EFI_SERVICE_BINDING_PROTOCOL mRedfishRestExServiceBinding; +extern EFI_REST_EX_PROTOCOL mRedfishRestExProtocol; +/// +/// RestEx service block +/// +typedef struct _RESTEX_SERVICE RESTEX_SERVICE; + +/// +/// RestEx instance block +/// +typedef struct _RESTEX_INSTANCE RESTEX_INSTANCE; + +/// +/// Driver Version +/// +#define REDFISH_RESTEX_DRIVER_VERSION 0x0100 + +#define RESTEX_SERVICE_SIGNATURE SIGNATURE_32 ('R', 'E', 'S', 'S') +#define RESTEX_INSTANCE_SIGNATURE SIGNATURE_32 ('R', 'E', 'I', 'S') + +#define RESTEX_SERVICE_FROM_THIS(a) \ + CR (a, RESTEX_SERVICE, ServiceBinding, RESTEX_SERVICE_SIGNATURE) + +#define RESTEX_INSTANCE_FROM_THIS(a) \ + CR (a, RESTEX_INSTANCE, RestEx, RESTEX_INSTANCE_SIGNATURE) + + +#define RESTEX_STATE_UNCONFIGED 0 +#define RESTEX_STATE_CONFIGED 1 + +struct _RESTEX_SERVICE { + UINT32 Signature; + EFI_SERVICE_BINDING_PROTOCOL ServiceBinding; + + UINT16 RestExChildrenNum; + LIST_ENTRY RestExChildrenList; + + EFI_HANDLE ControllerHandle; + EFI_HANDLE ImageHandle; + + // + // Use to establish the parent-child relationship. + // + EFI_HANDLE HttpChildHandle; + + UINT32 Id; + + EFI_REST_EX_SERVICE_INFO RestExServiceInfo; +}; + +#define RESTEX_INSTANCE_FLAGS_TLS_RETRY 0x00000001 +#define RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY 0x00000002 + +struct _RESTEX_INSTANCE { + UINT32 Signature; + LIST_ENTRY Link; + + EFI_REST_EX_PROTOCOL RestEx; + + INTN State; + BOOLEAN InDestroy; + + RESTEX_SERVICE *Service; + EFI_HANDLE ChildHandle; + + EFI_REST_EX_CONFIG_DATA ConfigData; + + // + // HTTP_IO to access the HTTP service + // + HTTP_IO HttpIo; + + UINT32 Flags; +}; + +typedef struct { + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + UINTN NumberOfChildren; + EFI_HANDLE *ChildHandleBuffer; +} RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT; + +/** + Provides a simple HTTP-like interface to send and receive resources from a REST service. + + The SendReceive() function sends an HTTP request to this REST service, and returns a + response when the data is retrieved from the service. RequestMessage contains the HTTP + request to the REST resource identified by RequestMessage.Request.Url. The + ResponseMessage is the returned HTTP response for that request, including any HTTP + status. + + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @param[in] RequestMessage Pointer to the HTTP request data for this resource + @param[out] ResponseMessage Pointer to the HTTP response data obtained for this requested. + + @retval EFI_SUCCESS operation succeeded. + @retval EFI_INVALID_PARAMETER This, RequestMessage, or ResponseMessage are NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExSendReceive ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_HTTP_MESSAGE *RequestMessage, + OUT EFI_HTTP_MESSAGE *ResponseMessage + ); + +/** + Obtain the current time from this REST service instance. + + The GetServiceTime() function is an optional interface to obtain the current time from + this REST service instance. If this REST service does not support to retrieve the time, + this function returns EFI_UNSUPPORTED. This function must returns EFI_UNSUPPORTED if + EFI_REST_EX_SERVICE_TYPE returned in EFI_REST_EX_SERVICE_INFO from GetService() is + EFI_REST_EX_SERVICE_UNSPECIFIC. + + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @param[out] Time A pointer to storage to receive a snapshot of the current time of + the REST service. + + @retval EFI_SUCCESS operation succeeded. + @retval EFI_INVALID_PARAMETER This or Time are NULL. + @retval EFI_UNSUPPORTED The RESTful service does not support returning the time. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must + be executed and returns successfully prior to invoke this function. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExGetServiceTime ( + IN EFI_REST_EX_PROTOCOL *This, + OUT EFI_TIME *Time + ); + +/** + This function returns the information of REST service provided by this EFI REST EX driver instance. + + The information such as the type of REST service and the access mode of REST EX driver instance + (In-band or Out-of-band) are described in EFI_REST_EX_SERVICE_INFO structure. For the vendor-specific + REST service, vendor-specific REST service information is returned in VendorSpecifcData. + REST EX driver designer is well know what REST service this REST EX driver instance intends to + communicate with. The designer also well know this driver instance is used to talk to BMC through + specific platform mechanism or talk to REST server through UEFI HTTP protocol. REST EX driver is + responsible to fill up the correct information in EFI_REST_EX_SERVICE_INFO. EFI_REST_EX_SERVICE_INFO + is referred by EFI REST clients to pickup the proper EFI REST EX driver instance to get and set resource. + GetService() is a basic and mandatory function which must be able to use even Configure() is not invoked + in previously. + + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @param[out] RestExServiceInfo Pointer to receive a pointer to EFI_REST_EX_SERVICE_INFO structure. The + format of EFI_REST_EX_SERVICE_INFO is version controlled for the future + extension. The version of EFI_REST_EX_SERVICE_INFO structure is returned + in the header within this structure. EFI REST client refers to the correct + format of structure according to the version number. The pointer to + EFI_REST_EX_SERVICE_INFO is a memory block allocated by EFI REST EX driver + instance. That is caller's responsibility to free this memory when this + structure is no longer needed. Refer to Related Definitions below for the + definitions of EFI_REST_EX_SERVICE_INFO structure. + + @retval EFI_SUCCESS EFI_REST_EX_SERVICE_INFO is returned in RestExServiceInfo. This function + is not supported in this REST EX Protocol driver instance. + @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExGetService ( + IN EFI_REST_EX_PROTOCOL *This, + OUT EFI_REST_EX_SERVICE_INFO **RestExServiceInfo + ); + +/** + This function returns operational configuration of current EFI REST EX child instance. + + This function returns the current configuration of EFI REST EX child instance. The format of + operational configuration depends on the implementation of EFI REST EX driver instance. For + example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol as the undying protocol + to communicate with REST service. In this case, the type of configuration is + EFI_REST_EX_CONFIG_TYPE_HTTP returned from GetService(). EFI_HTTP_CONFIG_DATA is used as EFI REST + EX configuration format and returned to EFI REST client. User has to type cast RestExConfigData + to EFI_HTTP_CONFIG_DATA. For those non HTTP-aware REST EX driver instances, the type of configuration + is EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC returned from GetService(). In this case, the format of + returning data could be non industrial. Instead, the format of configuration data is system/platform + specific definition such as BMC mechanism used in EFI REST EX driver instance. EFI REST client and + EFI REST EX driver instance have to refer to the specific system /platform spec which is out of UEFI scope. + + @param[in] This This is the EFI_REST_EX_PROTOCOL instance. + @param[out] RestExConfigData Pointer to receive a pointer to EFI_REST_EX_CONFIG_DATA. + The memory allocated for configuration data should be freed + by caller. See Related Definitions for the details. + + @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is returned in successfully. + @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance. + @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be + executed and returns successfully prior to invoke this function. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExGetModeData ( + IN EFI_REST_EX_PROTOCOL *This, + OUT EFI_REST_EX_CONFIG_DATA *RestExConfigData + ); + +/** + This function is used to configure EFI REST EX child instance. + + This function is used to configure the setting of underlying protocol of REST EX child + instance. The type of configuration is according to the implementation of EFI REST EX + driver instance. For example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol + as the undying protocol to communicate with REST service. The type of configuration is + EFI_REST_EX_CONFIG_TYPE_HTTP and RestExConfigData is the same format with EFI_HTTP_CONFIG_DATA. + Akin to HTTP configuration, REST EX child instance can be configure to use different HTTP + local access point for the data transmission. Multiple REST clients may use different + configuration of HTTP to distinguish themselves, such as to use the different TCP port. + For those non HTTP-aware REST EX driver instance, the type of configuration is + EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC. RestExConfigData refers to the non industrial standard. + Instead, the format of configuration data is system/platform specific definition such as BMC. + In this case, EFI REST client and EFI REST EX driver instance have to refer to the specific + system/platform spec which is out of the UEFI scope. Besides GetService()function, no other + EFI REST EX functions can be executed by this instance until Configure()is executed and returns + successfully. All other functions must returns EFI_NOT_READY if this instance is not configured + yet. Set RestExConfigData to NULL means to put EFI REST EX child instance into the unconfigured + state. + + @param[in] This This is the EFI_REST_EX_PROTOCOL instance. + @param[in] RestExConfigData Pointer to EFI_REST_EX_CONFIG_DATA. See Related Definitions in + GetModeData() protocol interface. + + @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is set in successfully. + @retval EFI_DEVICE_ERROR Configuration for this REST EX child instance is failed with the given + EFI_REST_EX_CONFIG_DATA. + @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExConfigure ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_REST_EX_CONFIG_DATA RestExConfigData + ); + +/** + This function sends REST request to REST service and signal caller's event asynchronously when + the final response is received by REST EX Protocol driver instance. + + The essential design of this function is to handle asynchronous send/receive implicitly according + to REST service asynchronous request mechanism. Caller will get the notification once the response + is returned from REST service. + + @param[in] This This is the EFI_REST_EX_PROTOCOL instance. + @param[in] RequestMessage This is the HTTP request message sent to REST service. Set RequestMessage + to NULL to cancel the previous asynchronous request associated with the + corresponding RestExToken. See descriptions for the details. + @param[in] RestExToken REST EX token which REST EX Protocol instance uses to notify REST client + the status of response of asynchronous REST request. See related definition + of EFI_REST_EX_TOKEN. + @param[in] TimeOutInMilliSeconds The pointer to the timeout in milliseconds which REST EX Protocol driver + instance refers as the duration to drop asynchronous REST request. NULL + pointer means no timeout for this REST request. REST EX Protocol driver + signals caller's event with EFI_STATUS set to EFI_TIMEOUT in RestExToken + if REST EX Protocol can't get the response from REST service within + TimeOutInMilliSeconds. + + @retval EFI_SUCCESS Asynchronous REST request is established. + @retval EFI_UNSUPPORTED This REST EX Protocol driver instance doesn't support asynchronous request. + @retval EFI_TIMEOUT Asynchronous REST request is not established and timeout is expired. + @retval EFI_ABORT Previous asynchronous REST request has been canceled. + @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR for other errors according to HTTP Status Code. + @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be executed + and returns successfully prior to invoke this function. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExAyncSendReceive ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, + IN EFI_REST_EX_TOKEN *RestExToken, + IN UINTN *TimeOutInMilliSeconds OPTIONAL + ); + +/** + This function sends REST request to a REST Event service and signals caller's event + token asynchronously when the URI resource change event is received by REST EX + Protocol driver instance. + + The essential design of this function is to monitor event implicitly according to + REST service event service mechanism. Caller will get the notification if certain + resource is changed. + + @param[in] This This is the EFI_REST_EX_PROTOCOL instance. + @param[in] RequestMessage This is the HTTP request message sent to REST service. Set RequestMessage + to NULL to cancel the previous event service associated with the corresponding + RestExToken. See descriptions for the details. + @param[in] RestExToken REST EX token which REST EX Protocol driver instance uses to notify REST client + the URI resource which monitored by REST client has been changed. See the related + definition of EFI_REST_EX_TOKEN in EFI_REST_EX_PROTOCOL.AsyncSendReceive(). + + @retval EFI_SUCCESS Asynchronous REST request is established. + @retval EFI_UNSUPPORTED This REST EX Protocol driver instance doesn't support asynchronous request. + @retval EFI_ABORT Previous asynchronous REST request has been canceled or event subscription has been + delete from service. + @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR for other errors according to HTTP Status Code. + @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be executed + and returns successfully prior to invoke this function. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExEventService ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, + IN EFI_REST_EX_TOKEN *RestExToken + ); +/** + Create a new TLS session becuase the previous on is closed. + status. + + @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @retval EFI_SUCCESS operation succeeded. + @retval EFI Errors Other errors. + +**/ +EFI_STATUS +ResetHttpTslSession ( + IN RESTEX_INSTANCE *Instance +); + + +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +EFIAPI +RestExDestroyChildEntryInHandleBuffer ( + IN LIST_ENTRY *Entry, + IN VOID *Context + ); + +/** + Destroy the RestEx instance and recycle the resources. + + @param[in] Instance The pointer to the RestEx instance. + +**/ +VOID +RestExDestroyInstance ( + IN RESTEX_INSTANCE *Instance + ); + +/** + Create the RestEx instance and initialize it. + + @param[in] Service The pointer to the RestEx service. + @param[out] Instance The pointer to the RestEx instance. + + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. + @retval EFI_SUCCESS The RestEx instance is created. + +**/ +EFI_STATUS +RestExCreateInstance ( + IN RESTEX_SERVICE *Service, + OUT RESTEX_INSTANCE **Instance + ); + + +/** + Release all the resource used the RestEx service binding instance. + + @param RestExSb The RestEx service binding instance. + +**/ +VOID +RestExDestroyService ( + IN RESTEX_SERVICE *RestExSb + ); + +/** + Create then initialize a RestEx service binding instance. + + @param[in] Controller The controller to install the RestEx service + binding on. + @param[in] Image The driver binding image of the RestEx driver. + @param[out] Service The variable to receive the created service + binding instance. + + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the instance. + @retval EFI_SUCCESS The service instance is created for the controller. + +**/ +EFI_STATUS +RestExCreateService ( + IN EFI_HANDLE Controller, + IN EFI_HANDLE Image, + OUT RESTEX_SERVICE **Service + ); + +/** + 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[in] ImageHandle The firmware allocated handle for the UEFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval Others An unexpected error occurred. +**/ +EFI_STATUS +EFIAPI +RedfishRestExDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + 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 +RedfishRestExDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +/** + 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 +RedfishRestExDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +/** + 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 +RedfishRestExDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ); + +/** + Creates a child handle and installs a protocol. + + The CreateChild() function installs a protocol on ChildHandle. + If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle. + If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle. + + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. + @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL, + then a new handle is created. If it is a pointer to an existing UEFI handle, + then the protocol is added to the existing UEFI handle. + + @retval EFI_SUCCES The protocol was added to ChildHandle. + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create + the child + @retval other The child handle was not created + +**/ +EFI_STATUS +EFIAPI +RedfishRestExServiceBindingCreateChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE *ChildHandle + ); + +/** + Destroys a child handle with a protocol installed on it. + + The DestroyChild() function does the opposite of CreateChild(). It removes a protocol + that was installed by CreateChild() from ChildHandle. If the removed protocol is the + last protocol on ChildHandle, then ChildHandle is destroyed. + + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. + @param[in] ChildHandle Handle of the child to destroy + + @retval EFI_SUCCES The protocol was removed from ChildHandle. + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed. + @retval EFI_INVALID_PARAMETER Child handle is NULL. + @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle + because its services are being used. + @retval other The child handle was not destroyed + +**/ +EFI_STATUS +EFIAPI +RedfishRestExServiceBindingDestroyChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE ChildHandle + ); +#endif diff --git a/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf new file mode 100644 index 00000000000..48c0f390cbc --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf @@ -0,0 +1,69 @@ +## @file +# Implementation of Redfish EFI_REST_EX_PROTOCOL interfaces. +# +# 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 = 0x0001001b + BASE_NAME = RedfishRestExDxe + FILE_GUID = B64702DA-E6B5-43c8-8CE8-D253071E9D6C + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + #ENTRY_POINT = RedfishRestExDriverEntryPoint + ENTRY_POINT = _MainEntryPointDxe + IMAGE_ENTRY_POINT = _cdeCRT0UefiDxeEDK + UNLOAD_IMAGE = NetLibDefaultUnload + MODULE_UNI_FILE = RedfishRestExDxe.uni + +[Packages] + CdePkg/CdePkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + NetworkPkg/NetworkPkg.dec + RedfishPkg/RedfishPkg.dec + +[Sources] + ComponentName.c + RedfishRestExDriver.c + RedfishRestExDriver.h + RedfishRestExImpl.c + RedfishRestExProtocol.c + RedfishRestExInternal.h + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DevicePathLib + DpcLib + HttpLib + HttpIoLib + PrintLib + MemoryAllocationLib + NetLib + UefiLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeServicesTableLib + CdeLib + +[Protocols] + gEfiRestExServiceBindingProtocolGuid ## BY_START + gEfiRestExProtocolGuid ## BY_START + gEfiHttpServiceBindingProtocolGuid ## TO_START + gEfiHttpProtocolGuid ## TO_START + gEfiDevicePathProtocolGuid ## TO_START + +[Pcd] + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceAccessModeInBand ## CONSUMES + +[UserExtensions.TianoCore."ExtraFiles"] + RedfishRestExDxeExtra.uni + +[Depex] + gCdeDxeProtocolGuid \ No newline at end of file diff --git a/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.uni b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.uni new file mode 100644 index 00000000000..330ea40d9f4 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.uni @@ -0,0 +1,16 @@ +// /** @file +// Redfish UEFI RESTEX DXE Driver. +// +// This driver provides Redfish UEFI RESTEX protocols. +// +// Copyright (c) 2019, Intel Corporation. All rights reserved.
+// (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "UEFI Redfish RESTEX service" + +#string STR_MODULE_DESCRIPTION #language en-US "This driver provides Redfish EFI RESTEX Protocol and Redfish EFI RESREX Service Binding Protocol." + diff --git a/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDxeExtra.uni b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDxeExtra.uni new file mode 100644 index 00000000000..49408e6cb40 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExDxeExtra.uni @@ -0,0 +1,15 @@ +// /** @file +// RestExDxe Localized Strings and Content +// +// Copyright (c) 2019, Intel Corporation. All rights reserved.
+// (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"Redfish UEFI RESTEX DXE" + + diff --git a/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c new file mode 100644 index 00000000000..c4de32f1d83 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c @@ -0,0 +1,157 @@ +/** @file + RestExDxe support functions implementation. + + 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 "RedfishRestExInternal.h" + +/** + Create a new TLS session becuase the previous on is closed. + status. + + @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @retval EFI_SUCCESS operation succeeded. + @retval EFI_ERROR Other errors. + +**/ +EFI_STATUS +ResetHttpTslSession ( + IN RESTEX_INSTANCE *Instance +) +{ + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "%a: TCP connection is finished. Could be TSL session closure, reset HTTP instance for the new TLS session.\n", __FUNCTION__)); + + Status = Instance->HttpIo.Http->Configure (Instance->HttpIo.Http, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Error to reset HTTP instance.\n", __FUNCTION__)); + return Status; + } + Status = Instance->HttpIo.Http->Configure(Instance->HttpIo.Http, &((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Error to re-initiate HTTP instance.\n", __FUNCTION__)); + } + return Status; +} +/** + This function check + + @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @param[in] HttpIoReceiveStatus This is the status return from HttpIoRecvResponse + + @retval EFI_SUCCESS The payload receive from Redfish service in successfully. + @retval EFI_NOT_READY May need to resend the HTTP request. + @retval EFI_DEVICE_ERROR Something wrong and can't be resolved. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +RedfishCheckHttpReceiveStatus ( + IN RESTEX_INSTANCE *Instance, + IN EFI_STATUS HttpIoReceiveStatus + ) +{ + EFI_STATUS Status; + EFI_STATUS ReturnStatus; + + if (!EFI_ERROR (HttpIoReceiveStatus)){ + ReturnStatus = EFI_SUCCESS; + } else if (EFI_ERROR (HttpIoReceiveStatus) && HttpIoReceiveStatus != EFI_CONNECTION_FIN) { + if ((Instance->Flags & RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY) == 0) { + DEBUG ((DEBUG_ERROR, "%a: TCP error, reset HTTP session.\n", __FUNCTION__)); + Instance->Flags |= RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY; + gBS->Stall (500); + Status = ResetHttpTslSession (Instance); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Reset HTTP instance fail.\n", __FUNCTION__)); + ReturnStatus = EFI_DEVICE_ERROR; + } else { + return EFI_NOT_READY; + } + } else { + ReturnStatus = EFI_DEVICE_ERROR; + } + } else { + if (HttpIoReceiveStatus == EFI_CONNECTION_FIN) { + if ((Instance->Flags & RESTEX_INSTANCE_FLAGS_TLS_RETRY) != 0) { + DEBUG ((DEBUG_ERROR, "%a: REST_EX Send and receive fail even with a new TLS session.\n", __FUNCTION__)); + ReturnStatus = EFI_DEVICE_ERROR; + } + Instance->Flags |= RESTEX_INSTANCE_FLAGS_TLS_RETRY; + Status = ResetHttpTslSession (Instance); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Reset HTTP instance fail.\n", __FUNCTION__)); + ReturnStatus = EFI_DEVICE_ERROR; + } + return EFI_NOT_READY; + } + } + // + // Clean TLS new session retry and error try flags. + // + Instance->Flags &= ~ (RESTEX_INSTANCE_FLAGS_TLS_RETRY | RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY); + return ReturnStatus; +} + +/** + This function send the HTTP request without body to see + if the write to URL is permitted by Redfish service. This function + checks if the HTTP request has Content-length in HTTP header. If yes, + set HTTP body to NULL and then send to service. Check the HTTP status + for the firther actions. + + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @param[in] RequestMessage Pointer to the HTTP request data for this resource + @param[in] PreservedRequestHeaders The pointer to save the request headers + @param[in] ItsWrite This is write method to URL. + + @retval EFI_INVALID_PARAMETER Improper given parameters. + @retval EFI_SUCCESS This HTTP request is free to send to Redfish service. + @retval EFI_OUT_OF_RESOURCES NOt enough memory to process. + @retval EFI_ACCESS_DENIED Not allowed to write to this URL. + + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +RedfishHttpAddExpectation ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_HTTP_MESSAGE *RequestMessage, + IN EFI_HTTP_HEADER **PreservedRequestHeaders, + IN BOOLEAN *ItsWrite + ) +{ + EFI_HTTP_HEADER *NewHeaders; + + if (This == NULL || RequestMessage == NULL) { + return EFI_INVALID_PARAMETER; + } + + *ItsWrite = FALSE; + if (PreservedRequestHeaders != NULL) { + *PreservedRequestHeaders = RequestMessage->Headers; + } + + if ((RequestMessage->Data.Request->Method != HttpMethodPut) && (RequestMessage->Data.Request->Method != HttpMethodPost) && + (RequestMessage->Data.Request->Method != HttpMethodPatch)) { + return EFI_SUCCESS; + } + *ItsWrite = TRUE; + + NewHeaders = AllocateZeroPool((RequestMessage->HeaderCount + 1) * sizeof(EFI_HTTP_HEADER)); + CopyMem ((VOID*)NewHeaders, (VOID *)RequestMessage->Headers, RequestMessage->HeaderCount * sizeof (EFI_HTTP_HEADER)); + HttpSetFieldNameAndValue (NewHeaders + RequestMessage->HeaderCount, HTTP_HEADER_EXPECT, HTTP_EXPECT_100_CONTINUE); + RequestMessage->HeaderCount ++; + RequestMessage->Headers = NewHeaders; + return EFI_SUCCESS; +} + diff --git a/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExInternal.h b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExInternal.h new file mode 100644 index 00000000000..4be5b890db3 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExInternal.h @@ -0,0 +1,611 @@ +/** @file + RedfishRestExDxe support functions definitions. + + Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2019-2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EFI_REDFISH_RESTEX_INTERNAL_H_ +#define EFI_REDFISH_RESTEX_INTERNAL_H_ + +/// +/// Libraries classes +/// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/// +/// UEFI Driver Model Protocols +/// +#include +#include +#include + +#include "RedfishRestExDriver.h" + +/** + This function check + + @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @param[in] HttpReceiveEfiStatus This is the status return from HttpIoRecvResponse + + @retval EFI_SUCCESS The payload receive from Redfish service in successfully. + @retval EFI_NOT_READY May need to resend the HTTP request. + @retval EFI_DEVICE_ERROR Something wrong and can't be resolved. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +RedfishCheckHttpReceiveStatus ( + IN RESTEX_INSTANCE *Instance, + IN EFI_STATUS HttpIoReceiveStatus + ); + +/** + This function send the HTTP request without body to see + if the write to URL is permitted by Redfish service. This function + checks if the HTTP request has Content-length in HTTP header. If yes, + set HTTP body to NULL and then send to service. Check the HTTP status + for the firther actions. + + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @param[in] RequestMessage Pointer to the HTTP request data for this resource + @param[in] PreservedRequestHeaders The pointer to save the request headers + @param[in] ItsWrite This is write method to URL. + + @retval EFI_INVALID_PARAMETER Improper given parameters. + @retval EFI_SUCCESS This HTTP request is free to send to Redfish service. + @retval EFI_OUT_OF_RESOURCES NOt enough memory to process. + @retval EFI_ACCESS_DENIED Not allowed to write to this URL. + + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +RedfishHttpAddExpectation ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_HTTP_MESSAGE *RequestMessage, + IN EFI_HTTP_HEADER **PreservedRequestHeaders, + IN BOOLEAN *ItsWrite + ); + +/** + Provides a simple HTTP-like interface to send and receive resources from a REST service. + + The SendReceive() function sends an HTTP request to this REST service, and returns a + response when the data is retrieved from the service. RequestMessage contains the HTTP + request to the REST resource identified by RequestMessage.Request.Url. The + ResponseMessage is the returned HTTP response for that request, including any HTTP + status. + + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @param[in] RequestMessage Pointer to the HTTP request data for this resource + @param[out] ResponseMessage Pointer to the HTTP response data obtained for this requested. + + @retval EFI_SUCCESS operation succeeded. + @retval EFI_INVALID_PARAMETER This, RequestMessage, or ResponseMessage are NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExSendReceive ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_HTTP_MESSAGE *RequestMessage, + OUT EFI_HTTP_MESSAGE *ResponseMessage + ); + +/** + Obtain the current time from this REST service instance. + + The GetServiceTime() function is an optional interface to obtain the current time from + this REST service instance. If this REST service does not support to retrieve the time, + this function returns EFI_UNSUPPORTED. This function must returns EFI_UNSUPPORTED if + EFI_REST_EX_SERVICE_TYPE returned in EFI_REST_EX_SERVICE_INFO from GetService() is + EFI_REST_EX_SERVICE_UNSPECIFIC. + + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @param[out] Time A pointer to storage to receive a snapshot of the current time of + the REST service. + + @retval EFI_SUCCESS operation succeeded. + @retval EFI_INVALID_PARAMETER This or Time are NULL. + @retval EFI_UNSUPPORTED The RESTful service does not support returning the time. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must + be executed and returns successfully prior to invoke this function. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExGetServiceTime ( + IN EFI_REST_EX_PROTOCOL *This, + OUT EFI_TIME *Time + ); + +/** + This function returns the information of REST service provided by this EFI REST EX driver instance. + + The information such as the type of REST service and the access mode of REST EX driver instance + (In-band or Out-of-band) are described in EFI_REST_EX_SERVICE_INFO structure. For the vendor-specific + REST service, vendor-specific REST service information is returned in VendorSpecifcData. + REST EX driver designer is well know what REST service this REST EX driver instance intends to + communicate with. The designer also well know this driver instance is used to talk to BMC through + specific platform mechanism or talk to REST server through UEFI HTTP protocol. REST EX driver is + responsible to fill up the correct information in EFI_REST_EX_SERVICE_INFO. EFI_REST_EX_SERVICE_INFO + is referred by EFI REST clients to pickup the proper EFI REST EX driver instance to get and set resource. + GetService() is a basic and mandatory function which must be able to use even Configure() is not invoked + in previously. + + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @param[out] RestExServiceInfo Pointer to receive a pointer to EFI_REST_EX_SERVICE_INFO structure. The + format of EFI_REST_EX_SERVICE_INFO is version controlled for the future + extension. The version of EFI_REST_EX_SERVICE_INFO structure is returned + in the header within this structure. EFI REST client refers to the correct + format of structure according to the version number. The pointer to + EFI_REST_EX_SERVICE_INFO is a memory block allocated by EFI REST EX driver + instance. That is caller's responsibility to free this memory when this + structure is no longer needed. Refer to Related Definitions below for the + definitions of EFI_REST_EX_SERVICE_INFO structure. + + @retval EFI_SUCCESS EFI_REST_EX_SERVICE_INFO is returned in RestExServiceInfo. This function + is not supported in this REST EX Protocol driver instance. + @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExGetService ( + IN EFI_REST_EX_PROTOCOL *This, + OUT EFI_REST_EX_SERVICE_INFO **RestExServiceInfo + ); + +/** + This function returns operational configuration of current EFI REST EX child instance. + + This function returns the current configuration of EFI REST EX child instance. The format of + operational configuration depends on the implementation of EFI REST EX driver instance. For + example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol as the undying protocol + to communicate with REST service. In this case, the type of configuration is + EFI_REST_EX_CONFIG_TYPE_HTTP returned from GetService(). EFI_HTTP_CONFIG_DATA is used as EFI REST + EX configuration format and returned to EFI REST client. User has to type cast RestExConfigData + to EFI_HTTP_CONFIG_DATA. For those non HTTP-aware REST EX driver instances, the type of configuration + is EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC returned from GetService(). In this case, the format of + returning data could be non industrial. Instead, the format of configuration data is system/platform + specific definition such as BMC mechanism used in EFI REST EX driver instance. EFI REST client and + EFI REST EX driver instance have to refer to the specific system /platform spec which is out of UEFI scope. + + @param[in] This This is the EFI_REST_EX_PROTOCOL instance. + @param[out] RestExConfigData Pointer to receive a pointer to EFI_REST_EX_CONFIG_DATA. + The memory allocated for configuration data should be freed + by caller. See Related Definitions for the details. + + @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is returned in successfully. + @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance. + @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be + executed and returns successfully prior to invoke this function. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExGetModeData ( + IN EFI_REST_EX_PROTOCOL *This, + OUT EFI_REST_EX_CONFIG_DATA *RestExConfigData + ); + +/** + This function is used to configure EFI REST EX child instance. + + This function is used to configure the setting of underlying protocol of REST EX child + instance. The type of configuration is according to the implementation of EFI REST EX + driver instance. For example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol + as the undying protocol to communicate with REST service. The type of configuration is + EFI_REST_EX_CONFIG_TYPE_HTTP and RestExConfigData is the same format with EFI_HTTP_CONFIG_DATA. + Akin to HTTP configuration, REST EX child instance can be configure to use different HTTP + local access point for the data transmission. Multiple REST clients may use different + configuration of HTTP to distinguish themselves, such as to use the different TCP port. + For those non HTTP-aware REST EX driver instance, the type of configuration is + EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC. RestExConfigData refers to the non industrial standard. + Instead, the format of configuration data is system/platform specific definition such as BMC. + In this case, EFI REST client and EFI REST EX driver instance have to refer to the specific + system/platform spec which is out of the UEFI scope. Besides GetService()function, no other + EFI REST EX functions can be executed by this instance until Configure()is executed and returns + successfully. All other functions must returns EFI_NOT_READY if this instance is not configured + yet. Set RestExConfigData to NULL means to put EFI REST EX child instance into the unconfigured + state. + + @param[in] This This is the EFI_REST_EX_PROTOCOL instance. + @param[in] RestExConfigData Pointer to EFI_REST_EX_CONFIG_DATA. See Related Definitions in + GetModeData() protocol interface. + + @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is set in successfully. + @retval EFI_DEVICE_ERROR Configuration for this REST EX child instance is failed with the given + EFI_REST_EX_CONFIG_DATA. + @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExConfigure ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_REST_EX_CONFIG_DATA RestExConfigData + ); + +/** + This function sends REST request to REST service and signal caller's event asynchronously when + the final response is received by REST EX Protocol driver instance. + + The essential design of this function is to handle asynchronous send/receive implicitly according + to REST service asynchronous request mechanism. Caller will get the notification once the response + is returned from REST service. + + @param[in] This This is the EFI_REST_EX_PROTOCOL instance. + @param[in] RequestMessage This is the HTTP request message sent to REST service. Set RequestMessage + to NULL to cancel the previous asynchronous request associated with the + corresponding RestExToken. See descriptions for the details. + @param[in] RestExToken REST EX token which REST EX Protocol instance uses to notify REST client + the status of response of asynchronous REST request. See related definition + of EFI_REST_EX_TOKEN. + @param[in] TimeOutInMilliSeconds The pointer to the timeout in milliseconds which REST EX Protocol driver + instance refers as the duration to drop asynchronous REST request. NULL + pointer means no timeout for this REST request. REST EX Protocol driver + signals caller's event with EFI_STATUS set to EFI_TIMEOUT in RestExToken + if REST EX Protocol can't get the response from REST service within + TimeOutInMilliSeconds. + + @retval EFI_SUCCESS Asynchronous REST request is established. + @retval EFI_UNSUPPORTED This REST EX Protocol driver instance doesn't support asynchronous request. + @retval EFI_TIMEOUT Asynchronous REST request is not established and timeout is expired. + @retval EFI_ABORT Previous asynchronous REST request has been canceled. + @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR for other errors according to HTTP Status Code. + @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be executed + and returns successfully prior to invoke this function. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExAyncSendReceive ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, + IN EFI_REST_EX_TOKEN *RestExToken, + IN UINTN *TimeOutInMilliSeconds OPTIONAL + ); + +/** + This function sends REST request to a REST Event service and signals caller's event + token asynchronously when the URI resource change event is received by REST EX + Protocol driver instance. + + The essential design of this function is to monitor event implicitly according to + REST service event service mechanism. Caller will get the notification if certain + resource is changed. + + @param[in] This This is the EFI_REST_EX_PROTOCOL instance. + @param[in] RequestMessage This is the HTTP request message sent to REST service. Set RequestMessage + to NULL to cancel the previous event service associated with the corresponding + RestExToken. See descriptions for the details. + @param[in] RestExToken REST EX token which REST EX Protocol driver instance uses to notify REST client + the URI resource which monitored by REST client has been changed. See the related + definition of EFI_REST_EX_TOKEN in EFI_REST_EX_PROTOCOL.AsyncSendReceive(). + + @retval EFI_SUCCESS Asynchronous REST request is established. + @retval EFI_UNSUPPORTED This REST EX Protocol driver instance doesn't support asynchronous request. + @retval EFI_ABORT Previous asynchronous REST request has been canceled or event subscription has been + delete from service. + @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR for other errors according to HTTP Status Code. + @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be executed + and returns successfully prior to invoke this function. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExEventService ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, + IN EFI_REST_EX_TOKEN *RestExToken + ); +/** + Create a new TLS session becuase the previous on is closed. + status. + + @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @retval EFI_SUCCESS operation succeeded. + @retval EFI Errors Other errors. + +**/ +EFI_STATUS +ResetHttpTslSession ( + IN RESTEX_INSTANCE *Instance +); + + +/** + Callback function which provided by user to remove one node in NetDestroyLinkList process. + + @param[in] Entry The entry to be removed. + @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. + + @retval EFI_SUCCESS The entry has been removed successfully. + @retval Others Fail to remove the entry. + +**/ +EFI_STATUS +EFIAPI +RestExDestroyChildEntryInHandleBuffer ( + IN LIST_ENTRY *Entry, + IN VOID *Context + ); + +/** + Destroy the RestEx instance and recycle the resources. + + @param[in] Instance The pointer to the RestEx instance. + +**/ +VOID +RestExDestroyInstance ( + IN RESTEX_INSTANCE *Instance + ); + +/** + Create the RestEx instance and initialize it. + + @param[in] Service The pointer to the RestEx service. + @param[out] Instance The pointer to the RestEx instance. + + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. + @retval EFI_SUCCESS The RestEx instance is created. + +**/ +EFI_STATUS +RestExCreateInstance ( + IN RESTEX_SERVICE *Service, + OUT RESTEX_INSTANCE **Instance + ); + + +/** + Release all the resource used the RestEx service binding instance. + + @param[in] RestExSb The RestEx service binding instance. + +**/ +VOID +RestExDestroyService ( + IN RESTEX_SERVICE *RestExSb + ); + +/** + Create then initialize a RestEx service binding instance. + + @param[in] Controller The controller to install the RestEx service + binding on. + @param[in] Image The driver binding image of the RestEx driver. + @param[out] Service The variable to receive the created service + binding instance. + + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the instance. + @retval EFI_SUCCESS The service instance is created for the controller. + +**/ +EFI_STATUS +RestExCreateService ( + IN EFI_HANDLE Controller, + IN EFI_HANDLE Image, + OUT RESTEX_SERVICE **Service + ); + +/** + 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[in] ImageHandle The firmware allocated handle for the UEFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval Others An unexpected error occurred. +**/ +EFI_STATUS +EFIAPI +RedfishRestExDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + 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 +RedfishRestExDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +/** + 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 +RedfishRestExDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +/** + 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 +RedfishRestExDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ); + +/** + Creates a child handle and installs a protocol. + + The CreateChild() function installs a protocol on ChildHandle. + If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle. + If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle. + + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. + @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL, + then a new handle is created. If it is a pointer to an existing UEFI handle, + then the protocol is added to the existing UEFI handle. + + @retval EFI_SUCCES The protocol was added to ChildHandle. + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create + the child + @retval other The child handle was not created + +**/ +EFI_STATUS +EFIAPI +RedfishRestExServiceBindingCreateChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE *ChildHandle + ); + +/** + Destroys a child handle with a protocol installed on it. + + The DestroyChild() function does the opposite of CreateChild(). It removes a protocol + that was installed by CreateChild() from ChildHandle. If the removed protocol is the + last protocol on ChildHandle, then ChildHandle is destroyed. + + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. + @param[in] ChildHandle Handle of the child to destroy + + @retval EFI_SUCCES The protocol was removed from ChildHandle. + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed. + @retval EFI_INVALID_PARAMETER Child handle is NULL. + @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle + because its services are being used. + @retval other The child handle was not destroyed + +**/ +EFI_STATUS +EFIAPI +RedfishRestExServiceBindingDestroyChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE ChildHandle + ); +#endif diff --git a/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExProtocol.c b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExProtocol.c new file mode 100644 index 00000000000..418fac29259 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RedfishRestExDxe/RedfishRestExProtocol.c @@ -0,0 +1,735 @@ +/** @file + Implementation of Redfish EFI_REST_EX_PROTOCOL interfaces. + + 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 "RedfishRestExInternal.h" + +EFI_REST_EX_PROTOCOL mRedfishRestExProtocol = { + RedfishRestExSendReceive, + RedfishRestExGetServiceTime, + RedfishRestExGetService, + RedfishRestExGetModeData, + RedfishRestExConfigure, + RedfishRestExAyncSendReceive, + RedfishRestExEventService +}; + +/** + Provides a simple HTTP-like interface to send and receive resources from a REST service. + + The SendReceive() function sends an HTTP request to this REST service, and returns a + response when the data is retrieved from the service. RequestMessage contains the HTTP + request to the REST resource identified by RequestMessage.Request.Url. The + ResponseMessage is the returned HTTP response for that request, including any HTTP + status. + + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @param[in] RequestMessage Pointer to the HTTP request data for this resource + @param[out] ResponseMessage Pointer to the HTTP response data obtained for this requested. + + @retval EFI_SUCCESS operation succeeded. + @retval EFI_INVALID_PARAMETER This, RequestMessage, or ResponseMessage are NULL. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_ACCESS_DENIED HTTP method is not allowed on this URL. + @retval EFI_BAD_BUFFER_SIZE The payload is to large to be handled on server side. + @retval EFI_UNSUPPORTED Unsupported HTTP response. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExSendReceive ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_HTTP_MESSAGE *RequestMessage, + OUT EFI_HTTP_MESSAGE *ResponseMessage + ) +{ + EFI_STATUS Status; + RESTEX_INSTANCE *Instance; + HTTP_IO_RESPONSE_DATA *ResponseData; + UINTN TotalReceivedSize; + UINTN Index; + LIST_ENTRY *ChunkListLink; + HTTP_IO_CHUNKS *ThisChunk; + BOOLEAN CopyChunkData; + BOOLEAN MediaPresent; + EFI_HTTP_HEADER *PreservedRequestHeaders; + BOOLEAN ItsWrite; + BOOLEAN IsGetChunkedTransfer; + HTTP_IO_SEND_CHUNK_PROCESS SendChunkProcess; + HTTP_IO_SEND_NON_CHUNK_PROCESS SendNonChunkProcess; + EFI_HTTP_MESSAGE ChunkTransferRequestMessage; + + Status = EFI_SUCCESS; + ResponseData = NULL; + IsGetChunkedTransfer = FALSE; + SendChunkProcess = HttpIoSendChunkNone; + SendNonChunkProcess = HttpIoSendNonChunkNone; + + // + // Validate the parameters + // + if ((This == NULL) || (RequestMessage == NULL) || ResponseMessage == NULL) { + return EFI_INVALID_PARAMETER; + } + + Instance = RESTEX_INSTANCE_FROM_THIS (This); + + // + // Check Media Status. + // + MediaPresent = TRUE; + NetLibDetectMedia (Instance->Service->ControllerHandle, &MediaPresent); + if (!MediaPresent) { + DEBUG ((DEBUG_INFO, "RedfishRestExSendReceive(): No MediaPresent.\n")); + return EFI_NO_MEDIA; + } + + DEBUG ((DEBUG_INFO, "\nRedfishRestExSendReceive():\n")); + DEBUG ((DEBUG_INFO, "*** Perform HTTP Request Method - %d, URL: %s\n", RequestMessage->Data.Request->Method, RequestMessage->Data.Request->Url)); + + // + // Add header "Expect" to server, only for URL write. + // + Status = RedfishHttpAddExpectation (This, RequestMessage, &PreservedRequestHeaders, &ItsWrite); + if (EFI_ERROR (Status)) { + return Status; + } + if (ItsWrite == TRUE) { + if (RequestMessage->BodyLength > HTTP_IO_MAX_SEND_PAYLOAD) { + // + // Send chunked transfer. + // + SendChunkProcess ++; + CopyMem ((VOID *)&ChunkTransferRequestMessage, (VOID *)RequestMessage, sizeof (EFI_HTTP_MESSAGE)); + } else { + SendNonChunkProcess ++; + } + } +ReSendRequest:; + // + // Send out the request to REST service. + // + if (ItsWrite == TRUE) { + // + // This is write to URI + // + if (SendChunkProcess > HttpIoSendChunkNone) { + // + // This is chunk transfer for writing large payload. + // Send request header first and then handle the + // following request message body using chunk transfer. + // + do { + Status = HttpIoSendChunkedTransfer( + &(Instance->HttpIo), + &SendChunkProcess, + &ChunkTransferRequestMessage + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + } while (SendChunkProcess == HttpIoSendChunkContent || SendChunkProcess == HttpIoSendChunkEndChunk); + } else { + // + // This is the non-chunk transfer, send request header first and then + // handle the following request message body using chunk transfer. + // + Status = HttpIoSendRequest( + &(Instance->HttpIo), + (SendNonChunkProcess == HttpIoSendNonChunkContent)? NULL: RequestMessage->Data.Request, + (SendNonChunkProcess == HttpIoSendNonChunkContent)? 0: RequestMessage->HeaderCount, + (SendNonChunkProcess == HttpIoSendNonChunkContent)? NULL: RequestMessage->Headers, + (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent)? 0: RequestMessage->BodyLength, + (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent)? NULL: RequestMessage->Body + ); + } + } else { + // + // This is read from URI. + // + Status = HttpIoSendRequest( + &(Instance->HttpIo), + RequestMessage->Data.Request, + RequestMessage->HeaderCount, + RequestMessage->Headers, + RequestMessage->BodyLength, + RequestMessage->Body + ); + } + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + // + // ResponseMessage->Data.Response is to indicate whether to receive the HTTP header or not. + // ResponseMessage->BodyLength/ResponseMessage->Body are to indicate whether to receive the response body or not. + // Clean the previous buffers and all of them will be allocated later according to the actual situation. + // + if (ResponseMessage->Data.Response != NULL) { + FreePool(ResponseMessage->Data.Response); + ResponseMessage->Data.Response = NULL; + } + + ResponseMessage->BodyLength = 0; + if (ResponseMessage->Body != NULL) { + FreePool(ResponseMessage->Body); + ResponseMessage->Body = NULL; + } + + // + // Use zero BodyLength to only receive the response headers. + // + ResponseData = AllocateZeroPool (sizeof(HTTP_IO_RESPONSE_DATA)); + if (ResponseData == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + DEBUG ((DEBUG_INFO, "Receiving HTTP response and headers...\n")); + Status = RedfishCheckHttpReceiveStatus ( + Instance, + HttpIoRecvResponse ( + &(Instance->HttpIo), + TRUE, + ResponseData + ) + ); + if (Status == EFI_NOT_READY) { + goto ReSendRequest; + } else if (Status == EFI_DEVICE_ERROR) { + goto ON_EXIT; + } + // + // Restore the headers if it ever changed in RedfishHttpAddExpectation(). + // + if (RequestMessage->Headers != PreservedRequestHeaders) { + FreePool (RequestMessage->Headers); + RequestMessage->Headers = PreservedRequestHeaders; // Restore headers before we adding "Expect". + RequestMessage->HeaderCount --; // Minus one header count for "Expect". + } + + DEBUG ((DEBUG_INFO, "HTTP Response StatusCode - %d:", ResponseData->Response.StatusCode)); + if (ResponseData->Response.StatusCode == HTTP_STATUS_200_OK) { + DEBUG ((DEBUG_INFO, "HTTP_STATUS_200_OK\n")); + + if (SendChunkProcess == HttpIoSendChunkHeaderZeroContent) { + DEBUG ((DEBUG_INFO, "This is chunk transfer, start to send all chunks.", ResponseData->Response.StatusCode)); + SendChunkProcess ++; + goto ReSendRequest; + } + } else if (ResponseData->Response.StatusCode == HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE) { + DEBUG ((DEBUG_INFO, "HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE\n")); + + Status = EFI_BAD_BUFFER_SIZE; + goto ON_EXIT; + } else if (ResponseData->Response.StatusCode == HTTP_STATUS_405_METHOD_NOT_ALLOWED){ + DEBUG ((DEBUG_ERROR, "HTTP_STATUS_405_METHOD_NOT_ALLOWED\n")); + + Status = EFI_ACCESS_DENIED; + goto ON_EXIT; + } else if (ResponseData->Response.StatusCode == HTTP_STATUS_400_BAD_REQUEST) { + DEBUG ((DEBUG_INFO, "HTTP_STATUS_400_BAD_REQUEST\n")); + if (SendChunkProcess == HttpIoSendChunkHeaderZeroContent) { + DEBUG ((DEBUG_INFO, "Bad request may caused by zero length chunk. Try to send all chunks...\n")); + SendChunkProcess ++; + goto ReSendRequest; + } + } else if (ResponseData->Response.StatusCode == HTTP_STATUS_100_CONTINUE) { + DEBUG ((DEBUG_INFO, "HTTP_STATUS_100_CONTINUE\n")); + if (SendChunkProcess == HttpIoSendChunkHeaderZeroContent) { + // + // We get HTTP_STATUS_100_CONTINUE to send the body using chunk transfer. + // + DEBUG ((DEBUG_INFO, "HTTP_STATUS_100_CONTINUE for chunk transfer...\n")); + SendChunkProcess ++; + goto ReSendRequest; + } + if (SendNonChunkProcess == HttpIoSendNonChunkHeaderZeroContent) { + DEBUG ((DEBUG_INFO, "HTTP_STATUS_100_CONTINUE for non chunk transfer...\n")); + SendNonChunkProcess ++; + goto ReSendRequest; + } + // + // It's the REST protocol's responsibility to handle the interim HTTP response (e.g. 100 Continue Informational), + // and return the final response content to the caller. + // + if (ResponseData->Headers != NULL && ResponseData->HeaderCount != 0) { + FreePool (ResponseData->Headers); + } + ZeroMem (ResponseData, sizeof(HTTP_IO_RESPONSE_DATA)); + Status = HttpIoRecvResponse ( + &(Instance->HttpIo), + TRUE, + ResponseData + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + } else { + DEBUG ((DEBUG_ERROR, "This HTTP Status is not handled!\n")); + Status = EFI_UNSUPPORTED; + goto ON_EXIT; + } + + // + // Ready to return the StatusCode, Header info and BodyLength. + // + ResponseMessage->Data.Response = AllocateZeroPool (sizeof (EFI_HTTP_RESPONSE_DATA)); + if (ResponseMessage->Data.Response == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + ResponseMessage->Data.Response->StatusCode = ResponseData->Response.StatusCode; + ResponseMessage->HeaderCount = ResponseData->HeaderCount; + ResponseMessage->Headers = ResponseData->Headers; + + // + // Get response message body. + // + if (ResponseMessage->HeaderCount > 0) { + Status = HttpIoGetContentLength (ResponseMessage->HeaderCount, ResponseMessage->Headers, &ResponseMessage->BodyLength); + if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) { + goto ON_EXIT; + } + + if (Status == EFI_NOT_FOUND) { + ASSERT (ResponseMessage->BodyLength == 0); + } + + if (ResponseMessage->BodyLength == 0) { + // + // Check if Chunked Transfer Coding. + // + Status = HttpIoGetChunkedTransferContent ( + &(Instance->HttpIo), + ResponseMessage->HeaderCount, + ResponseMessage->Headers, + &ChunkListLink, + &ResponseMessage->BodyLength + ); + if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) { + goto ON_EXIT; + } + if (Status == EFI_SUCCESS && + ChunkListLink != NULL && + !IsListEmpty(ChunkListLink) && + ResponseMessage->BodyLength != 0) { + IsGetChunkedTransfer = TRUE; + // + // Copy data to Message body. + // + CopyChunkData = TRUE; + ResponseMessage->Body = AllocateZeroPool (ResponseMessage->BodyLength); + if (ResponseMessage->Body == NULL) { + Status = EFI_OUT_OF_RESOURCES; + CopyChunkData = FALSE; + } + Index = 0; + while (!IsListEmpty(ChunkListLink)) { + ThisChunk = (HTTP_IO_CHUNKS *)GetFirstNode (ChunkListLink); + if (CopyChunkData) { + CopyMem(((UINT8 *)ResponseMessage->Body + Index), (UINT8 *)ThisChunk->Data, ThisChunk->Length); + Index += ThisChunk->Length; + } + RemoveEntryList (&ThisChunk->NextChunk); + FreePool ((VOID *)ThisChunk->Data); + FreePool ((VOID *)ThisChunk); + }; + FreePool ((VOID *)ChunkListLink); + } + } + Status = EFI_SUCCESS; + } + + // + // Ready to return the Body from REST service if have any. + // + if (ResponseMessage->BodyLength > 0 && !IsGetChunkedTransfer) { + ResponseData->HeaderCount = 0; + ResponseData->Headers = NULL; + + ResponseMessage->Body = AllocateZeroPool (ResponseMessage->BodyLength); + if (ResponseMessage->Body == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + // + // Only receive the Body. + // + TotalReceivedSize = 0; + while (TotalReceivedSize < ResponseMessage->BodyLength) { + ResponseData->BodyLength = ResponseMessage->BodyLength - TotalReceivedSize; + ResponseData->Body = (CHAR8 *) ResponseMessage->Body + TotalReceivedSize; + Status = HttpIoRecvResponse ( + &(Instance->HttpIo), + FALSE, + ResponseData + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + TotalReceivedSize += ResponseData->BodyLength; + } + DEBUG ((DEBUG_INFO, "Total of lengh of Response :%d\n", TotalReceivedSize)); + } + DEBUG ((DEBUG_INFO, "RedfishRestExSendReceive()- EFI_STATUS: %r\n", Status)); + +ON_EXIT: + + if (ResponseData != NULL) { + FreePool (ResponseData); + } + + if (EFI_ERROR (Status)) { + if (ResponseMessage->Data.Response != NULL) { + FreePool (ResponseMessage->Data.Response); + ResponseMessage->Data.Response = NULL; + } + + if (ResponseMessage->Body != NULL) { + FreePool (ResponseMessage->Body); + ResponseMessage->Body = NULL; + } + } + return Status; +} + +/** + Obtain the current time from this REST service instance. + + The GetServiceTime() function is an optional interface to obtain the current time from + this REST service instance. If this REST service does not support to retrieve the time, + this function returns EFI_UNSUPPORTED. This function must returns EFI_UNSUPPORTED if + EFI_REST_EX_SERVICE_TYPE returned in EFI_REST_EX_SERVICE_INFO from GetService() is + EFI_REST_EX_SERVICE_UNSPECIFIC. + + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @param[out] Time A pointer to storage to receive a snapshot of the current time of + the REST service. + + @retval EFI_SUCCESS operation succeeded. + @retval EFI_INVALID_PARAMETER This or Time are NULL. + @retval EFI_UNSUPPORTED The RESTful service does not support returning the time. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must + be executed and returns successfully prior to invoke this function. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExGetServiceTime ( + IN EFI_REST_EX_PROTOCOL *This, + OUT EFI_TIME *Time + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This function returns the information of REST service provided by this EFI REST EX driver instance. + + The information such as the type of REST service and the access mode of REST EX driver instance + (In-band or Out-of-band) are described in EFI_REST_EX_SERVICE_INFO structure. For the vendor-specific + REST service, vendor-specific REST service information is returned in VendorSpecifcData. + REST EX driver designer is well know what REST service this REST EX driver instance intends to + communicate with. The designer also well know this driver instance is used to talk to BMC through + specific platform mechanism or talk to REST server through UEFI HTTP protocol. REST EX driver is + responsible to fill up the correct information in EFI_REST_EX_SERVICE_INFO. EFI_REST_EX_SERVICE_INFO + is referred by EFI REST clients to pickup the proper EFI REST EX driver instance to get and set resource. + GetService() is a basic and mandatory function which must be able to use even Configure() is not invoked + in previously. + + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instance for a particular + REST service. + @param[out] RestExServiceInfo Pointer to receive a pointer to EFI_REST_EX_SERVICE_INFO structure. The + format of EFI_REST_EX_SERVICE_INFO is version controlled for the future + extension. The version of EFI_REST_EX_SERVICE_INFO structure is returned + in the header within this structure. EFI REST client refers to the correct + format of structure according to the version number. The pointer to + EFI_REST_EX_SERVICE_INFO is a memory block allocated by EFI REST EX driver + instance. That is caller's responsibility to free this memory when this + structure is no longer needed. Refer to Related Definitions below for the + definitions of EFI_REST_EX_SERVICE_INFO structure. + + @retval EFI_SUCCESS EFI_REST_EX_SERVICE_INFO is returned in RestExServiceInfo. This function + is not supported in this REST EX Protocol driver instance. + @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExGetService ( + IN EFI_REST_EX_PROTOCOL *This, + OUT EFI_REST_EX_SERVICE_INFO **RestExServiceInfo + ) +{ + EFI_TPL OldTpl; + RESTEX_INSTANCE *Instance; + EFI_REST_EX_SERVICE_INFO *ServiceInfo; + + ServiceInfo = NULL; + + if (This == NULL || RestExServiceInfo == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Instance = RESTEX_INSTANCE_FROM_THIS (This); + + ServiceInfo = AllocateZeroPool (sizeof (EFI_REST_EX_SERVICE_INFO)); + if (ServiceInfo == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (ServiceInfo, &(Instance->Service->RestExServiceInfo), sizeof (EFI_REST_EX_SERVICE_INFO)); + + *RestExServiceInfo = ServiceInfo; + + gBS->RestoreTPL (OldTpl); + + return EFI_SUCCESS; +} + +/** + This function returns operational configuration of current EFI REST EX child instance. + + This function returns the current configuration of EFI REST EX child instance. The format of + operational configuration depends on the implementation of EFI REST EX driver instance. For + example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol as the undying protocol + to communicate with REST service. In this case, the type of configuration is + EFI_REST_EX_CONFIG_TYPE_HTTP returned from GetService(). EFI_HTTP_CONFIG_DATA is used as EFI REST + EX configuration format and returned to EFI REST client. User has to type cast RestExConfigData + to EFI_HTTP_CONFIG_DATA. For those non HTTP-aware REST EX driver instances, the type of configuration + is EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC returned from GetService(). In this case, the format of + returning data could be non industrial. Instead, the format of configuration data is system/platform + specific definition such as BMC mechanism used in EFI REST EX driver instance. EFI REST client and + EFI REST EX driver instance have to refer to the specific system /platform spec which is out of UEFI scope. + + @param[in] This This is the EFI_REST_EX_PROTOCOL instance. + @param[out] RestExConfigData Pointer to receive a pointer to EFI_REST_EX_CONFIG_DATA. + The memory allocated for configuration data should be freed + by caller. See Related Definitions for the details. + + @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is returned in successfully. + @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance. + @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be + executed and returns successfully prior to invoke this function. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExGetModeData ( + IN EFI_REST_EX_PROTOCOL *This, + OUT EFI_REST_EX_CONFIG_DATA *RestExConfigData + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This function is used to configure EFI REST EX child instance. + + This function is used to configure the setting of underlying protocol of REST EX child + instance. The type of configuration is according to the implementation of EFI REST EX + driver instance. For example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol + as the undying protocol to communicate with REST service. The type of configuration is + EFI_REST_EX_CONFIG_TYPE_HTTP and RestExConfigData is the same format with EFI_HTTP_CONFIG_DATA. + Akin to HTTP configuration, REST EX child instance can be configure to use different HTTP + local access point for the data transmission. Multiple REST clients may use different + configuration of HTTP to distinguish themselves, such as to use the different TCP port. + For those non HTTP-aware REST EX driver instance, the type of configuration is + EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC. RestExConfigData refers to the non industrial standard. + Instead, the format of configuration data is system/platform specific definition such as BMC. + In this case, EFI REST client and EFI REST EX driver instance have to refer to the specific + system/platform spec which is out of the UEFI scope. Besides GetService()function, no other + EFI REST EX functions can be executed by this instance until Configure()is executed and returns + successfully. All other functions must returns EFI_NOT_READY if this instance is not configured + yet. Set RestExConfigData to NULL means to put EFI REST EX child instance into the unconfigured + state. + + @param[in] This This is the EFI_REST_EX_PROTOCOL instance. + @param[in] RestExConfigData Pointer to EFI_REST_EX_CONFIG_DATA. See Related Definitions in + GetModeData() protocol interface. + + @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is set in successfully. + @retval EFI_DEVICE_ERROR Configuration for this REST EX child instance is failed with the given + EFI_REST_EX_CONFIG_DATA. + @retval EFI_UNSUPPORTED This function is not supported in this REST EX Protocol driver instance. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExConfigure ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_REST_EX_CONFIG_DATA RestExConfigData + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + RESTEX_INSTANCE *Instance; + + EFI_HTTP_CONFIG_DATA *HttpConfigData; + + Status = EFI_SUCCESS; + HttpConfigData = NULL; + + if (This == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Instance = RESTEX_INSTANCE_FROM_THIS (This); + + if (RestExConfigData == NULL) { + // + // Set RestExConfigData to NULL means to put EFI REST EX child instance into the unconfigured state. + // + HttpIoDestroyIo (&(Instance->HttpIo)); + + if (Instance->ConfigData != NULL) { + if (((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv4Node != NULL) { + FreePool(((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv4Node); + } + FreePool(Instance->ConfigData); + Instance->ConfigData = NULL; + } + + Instance->State = RESTEX_STATE_UNCONFIGED; + } else { + HttpConfigData = &((EFI_REST_EX_HTTP_CONFIG_DATA *)RestExConfigData)->HttpConfigData; + Status = Instance->HttpIo.Http->Configure (Instance->HttpIo.Http, HttpConfigData); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + Instance->HttpIo.Timeout = ((EFI_REST_EX_HTTP_CONFIG_DATA *)RestExConfigData)->SendReceiveTimeout; + + Instance->ConfigData = AllocateZeroPool (sizeof (EFI_REST_EX_HTTP_CONFIG_DATA)); + if (Instance->ConfigData == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + CopyMem (Instance->ConfigData, RestExConfigData, sizeof (EFI_REST_EX_HTTP_CONFIG_DATA)); + if (HttpConfigData->LocalAddressIsIPv6 == TRUE) { + ((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv6Node = AllocateZeroPool (sizeof (EFI_HTTPv6_ACCESS_POINT)); + if (((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv6Node == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + CopyMem ( + ((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv6Node, + HttpConfigData->AccessPoint.IPv6Node, + sizeof (EFI_HTTPv6_ACCESS_POINT) + ); + } else { + ((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv4Node = AllocateZeroPool (sizeof (EFI_HTTPv4_ACCESS_POINT)); + if (((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv4Node == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + CopyMem ( + ((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)->HttpConfigData.AccessPoint.IPv4Node, + HttpConfigData->AccessPoint.IPv4Node, + sizeof (EFI_HTTPv4_ACCESS_POINT) + ); + } + Instance->State = RESTEX_STATE_CONFIGED; + } + +ON_EXIT: + gBS->RestoreTPL (OldTpl); + return Status; +} + +/** + This function sends REST request to REST service and signal caller's event asynchronously when + the final response is received by REST EX Protocol driver instance. + + The essential design of this function is to handle asynchronous send/receive implicitly according + to REST service asynchronous request mechanism. Caller will get the notification once the response + is returned from REST service. + + @param[in] This This is the EFI_REST_EX_PROTOCOL instance. + @param[in] RequestMessage This is the HTTP request message sent to REST service. Set RequestMessage + to NULL to cancel the previous asynchronous request associated with the + corresponding RestExToken. See descriptions for the details. + @param[in] RestExToken REST EX token which REST EX Protocol instance uses to notify REST client + the status of response of asynchronous REST request. See related definition + of EFI_REST_EX_TOKEN. + @param[in] TimeOutInMilliSeconds The pointer to the timeout in milliseconds which REST EX Protocol driver + instance refers as the duration to drop asynchronous REST request. NULL + pointer means no timeout for this REST request. REST EX Protocol driver + signals caller's event with EFI_STATUS set to EFI_TIMEOUT in RestExToken + if REST EX Protocol can't get the response from REST service within + TimeOutInMilliSeconds. + + @retval EFI_SUCCESS Asynchronous REST request is established. + @retval EFI_UNSUPPORTED This REST EX Protocol driver instance doesn't support asynchronous request. + @retval EFI_TIMEOUT Asynchronous REST request is not established and timeout is expired. + @retval EFI_ABORT Previous asynchronous REST request has been canceled. + @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR for other errors according to HTTP Status Code. + @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be executed + and returns successfully prior to invoke this function. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExAyncSendReceive ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, + IN EFI_REST_EX_TOKEN *RestExToken, + IN UINTN *TimeOutInMilliSeconds OPTIONAL + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This function sends REST request to a REST Event service and signals caller's event + token asynchronously when the URI resource change event is received by REST EX + Protocol driver instance. + + The essential design of this function is to monitor event implicitly according to + REST service event service mechanism. Caller will get the notification if certain + resource is changed. + + @param[in] This This is the EFI_REST_EX_PROTOCOL instance. + @param[in] RequestMessage This is the HTTP request message sent to REST service. Set RequestMessage + to NULL to cancel the previous event service associated with the corresponding + RestExToken. See descriptions for the details. + @param[in] RestExToken REST EX token which REST EX Protocol driver instance uses to notify REST client + the URI resource which monitored by REST client has been changed. See the related + definition of EFI_REST_EX_TOKEN in EFI_REST_EX_PROTOCOL.AsyncSendReceive(). + + @retval EFI_SUCCESS Asynchronous REST request is established. + @retval EFI_UNSUPPORTED This REST EX Protocol driver instance doesn't support asynchronous request. + @retval EFI_ABORT Previous asynchronous REST request has been canceled or event subscription has been + delete from service. + @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR for other errors according to HTTP Status Code. + @retval EFI_NOT_READY The configuration of this instance is not set yet. Configure() must be executed + and returns successfully prior to invoke this function. + +**/ +EFI_STATUS +EFIAPI +RedfishRestExEventService ( + IN EFI_REST_EX_PROTOCOL *This, + IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, + IN EFI_REST_EX_TOKEN *RestExToken + ) +{ + return EFI_UNSUPPORTED; +} + diff --git a/CdeEmuPkg/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c b/CdeEmuPkg/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c new file mode 100644 index 00000000000..61c76774491 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c @@ -0,0 +1,1434 @@ +/** @file + + The implementation of EFI REST Resource JSON to C structure convertor + Protocol. + + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + + +#include +#include +#include "RestJsonStructureInternal.h" +#include +#include +#include +#include +#include +#include +#include +#include +//extern int isdchar (int c); +#define TWSTRING L"\"a b c\"" /*TEST STRING*/ +#define TWSTRING2 L"\"E F G\"" /*TEST STRING 2*/ +#define ELC(x) (sizeof(x) / sizeof(x[0])) +enum { HDADDRSIZE64, HDADDRSIZE32, HDADDRSIZE16, HDADDRSIZE8, HDADDRSIZE0 }; +enum { HDELMSIZE1, HDELMSIZE2, HDELMSIZEx0 = 0, HDELMSIZE4 = 3, HDELMSIZEx1 = 0, HDELMSIZEx2 = 0, HDELMSIZEx3 = 0, HDELMSIZE64 = 7 }; + +typedef union _UNIDUMPPARM { + unsigned reg; + struct { + unsigned elmsizemin1 : 3; /*!NextSupportedRsrcInterp; + NumberOfNS = 1; + while (TRUE) { + if (ThisList->ForwardLink == &JsonStructureSupported->NextSupportedRsrcInterp) { + break; + } else { + ThisList = ThisList->ForwardLink; + NumberOfNS ++; + } + }; + + Instance = + (REST_JSON_STRUCTURE_INSTANCE *)AllocateZeroPool (sizeof (REST_JSON_STRUCTURE_INSTANCE) + NumberOfNS * sizeof (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER)); + if (Instance == NULL) { + return EFI_OUT_OF_RESOURCES; + } + InitializeListHead (&Instance->NextRestJsonStructureInstance); + Instance->NumberOfNameSpaceToConvert = NumberOfNS; + Instance->SupportedRsrcIndentifier = (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *)((REST_JSON_STRUCTURE_INSTANCE *)Instance + 1); + // + // Copy supported resource identifer interpreter. + // + CloneSupportedInterpId = Instance->SupportedRsrcIndentifier; + ThisSupportedInterp = JsonStructureSupported; + for (Index = 0; Index < NumberOfNS; Index ++) { + CopyMem ((VOID *)CloneSupportedInterpId, (VOID *)&ThisSupportedInterp->RestResourceInterp, sizeof (EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER)); + ThisSupportedInterp = (EFI_REST_JSON_STRUCTURE_SUPPORTED *)ThisSupportedInterp->NextSupportedRsrcInterp.ForwardLink; + CloneSupportedInterpId ++; + } + Instance->JsonToStructure = ToStructure; + Instance->StructureToJson = ToJson; + Instance->DestroyStructure = DestroyStructure; + InsertTailList (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); + return EFI_SUCCESS; +} + +/** + This function check if this interpreter instance support the given namesapce. + + @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. + @param[in] InterpreterInstance REST_JSON_STRUCTURE_INSTANCE + @param[in] RsrcTypeIdentifier Resource type identifier. + @param[in] ResourceRaw Given Restful resource. + @param[out] RestJSonHeader Property interpreted from given ResourceRaw. + + @retval EFI_SUCCESS + @retval Others. + +**/ +EFI_STATUS +InterpreterInstanceToStruct ( + IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, + IN REST_JSON_STRUCTURE_INSTANCE *InterpreterInstance, + IN EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier OPTIONAL, + IN CHAR8 *ResourceRaw, + OUT EFI_REST_JSON_STRUCTURE_HEADER **RestJSonHeader + ) +{ + UINTN Index; + EFI_STATUS Status; + EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId; + + if (This == NULL || + InterpreterInstance == NULL || + ResourceRaw == NULL || + RestJSonHeader == NULL + ) { + return EFI_INVALID_PARAMETER; + } + + Status = EFI_UNSUPPORTED; + if (RsrcTypeIdentifier == NULL) { + // + // No resource type identifier, send to intepreter anyway. + // Interpreter may recognize this resource. + // + Status = InterpreterInstance->JsonToStructure ( + This, + NULL, + ResourceRaw, + RestJSonHeader + ); + } else { + // + // Check if the namesapce and version is supported by this interpreter. + // + ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier; + for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index ++){ + if (AsciiStrCmp ( + RsrcTypeIdentifier->NameSpace.ResourceTypeName, + ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName) == 0){ + if ((RsrcTypeIdentifier->NameSpace.MajorVersion == NULL) && + (RsrcTypeIdentifier->NameSpace.MinorVersion == NULL) && + (RsrcTypeIdentifier->NameSpace.ErrataVersion == NULL) + ) { + // + // Don't check version of this resource type identifier. + // + Status = InterpreterInstance->JsonToStructure ( + This, + RsrcTypeIdentifier, + ResourceRaw, + RestJSonHeader + ); + break; + } else { + // + // Check version. + // + if ((AsciiStrCmp ( + RsrcTypeIdentifier->NameSpace.MajorVersion, + ThisSupportedRsrcTypeId->NameSpace.MajorVersion) == 0) && + (AsciiStrCmp ( + RsrcTypeIdentifier->NameSpace.MinorVersion, + ThisSupportedRsrcTypeId->NameSpace.MinorVersion) == 0) && + (AsciiStrCmp ( + RsrcTypeIdentifier->NameSpace.ErrataVersion, + ThisSupportedRsrcTypeId->NameSpace.ErrataVersion) == 0)) { + Status = InterpreterInstance->JsonToStructure ( + This, + RsrcTypeIdentifier, + ResourceRaw, + RestJSonHeader + ); + break; + } + } + } + ThisSupportedRsrcTypeId ++; + } + } + return Status; +} +/** + This function converts JSON C structure to JSON property. + + @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. + @param[in] InterpreterInstance REST_JSON_STRUCTURE_INSTANCE + @param[in] RestJSonHeader Resource type identifier. + @param[out] ResourceRaw Output in JSON text format. + + @retval EFI_SUCCESS + @retval Others. + +**/ +EFI_STATUS +InterpreterEfiStructToInstance ( + IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, + IN REST_JSON_STRUCTURE_INSTANCE *InterpreterInstance, + IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader, + OUT CHAR8 **ResourceRaw +) +{ + UINTN Index; + EFI_STATUS Status; + EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId; + EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier; + + if (This == NULL || + InterpreterInstance == NULL || + RestJSonHeader == NULL || + ResourceRaw == NULL + ) { + return EFI_INVALID_PARAMETER; + } + RsrcTypeIdentifier = &RestJSonHeader->JsonRsrcIdentifier; + if (RsrcTypeIdentifier == NULL || + RsrcTypeIdentifier->NameSpace.ResourceTypeName == NULL || + RsrcTypeIdentifier->NameSpace.MajorVersion == NULL || + RsrcTypeIdentifier->NameSpace.MinorVersion == NULL || + RsrcTypeIdentifier->NameSpace.ErrataVersion == NULL + ) { + return EFI_INVALID_PARAMETER; + } + + // + // Check if the namesapce and version is supported by this interpreter. + // + Status = EFI_UNSUPPORTED; + ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier; + for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index ++){ + if (AsciiStrCmp ( + RsrcTypeIdentifier->NameSpace.ResourceTypeName, + ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName) == 0){ + // + // Check version. + // + if ((AsciiStrCmp ( + RsrcTypeIdentifier->NameSpace.MajorVersion, + ThisSupportedRsrcTypeId->NameSpace.MajorVersion) == 0) && + (AsciiStrCmp ( + RsrcTypeIdentifier->NameSpace.MinorVersion, + ThisSupportedRsrcTypeId->NameSpace.MinorVersion) == 0) && + (AsciiStrCmp ( + RsrcTypeIdentifier->NameSpace.ErrataVersion, + ThisSupportedRsrcTypeId->NameSpace.ErrataVersion) == 0)) { + Status = InterpreterInstance->StructureToJson ( + This, + RestJSonHeader, + ResourceRaw + ); + break; + } + } + ThisSupportedRsrcTypeId ++; + } + return Status; +} + +/** + This function destory REST property structure. + + @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. + @param[in] InterpreterInstance REST_JSON_STRUCTURE_INSTANCE + @param[in] RestJSonHeader Property interpreted from given ResourceRaw. + + @retval EFI_SUCCESS + @retval Others. + +**/ +EFI_STATUS +InterpreterInstanceDestoryJsonStruct ( + IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, + IN REST_JSON_STRUCTURE_INSTANCE *InterpreterInstance, + IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader + ) +{ + UINTN Index; + EFI_STATUS Status; + EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *ThisSupportedRsrcTypeId; + + if (This == NULL || + InterpreterInstance == NULL || + RestJSonHeader == NULL + ) { + return EFI_INVALID_PARAMETER; + } + + Status = EFI_UNSUPPORTED; + // + // Check if the namesapce and version is supported by this interpreter. + // + ThisSupportedRsrcTypeId = InterpreterInstance->SupportedRsrcIndentifier; + for (Index = 0; Index < InterpreterInstance->NumberOfNameSpaceToConvert; Index ++){ + if (AsciiStrCmp ( + RestJSonHeader->JsonRsrcIdentifier.NameSpace.ResourceTypeName, + ThisSupportedRsrcTypeId->NameSpace.ResourceTypeName) == 0) { + if ((RestJSonHeader->JsonRsrcIdentifier.NameSpace.MajorVersion == NULL) && + (RestJSonHeader->JsonRsrcIdentifier.NameSpace.MinorVersion == NULL) && + (RestJSonHeader->JsonRsrcIdentifier.NameSpace.ErrataVersion == NULL) + ) { + // + // Don't check version of this resource type identifier. + // + Status = InterpreterInstance->DestroyStructure ( + This, + RestJSonHeader + ); + break; + } else { + // + // Check version. + // + if ((AsciiStrCmp ( + RestJSonHeader->JsonRsrcIdentifier.NameSpace.MajorVersion, + ThisSupportedRsrcTypeId->NameSpace.MajorVersion) == 0) && + (AsciiStrCmp ( + RestJSonHeader->JsonRsrcIdentifier.NameSpace.MinorVersion, + ThisSupportedRsrcTypeId->NameSpace.MinorVersion) == 0) && + (AsciiStrCmp ( + RestJSonHeader->JsonRsrcIdentifier.NameSpace.ErrataVersion, + ThisSupportedRsrcTypeId->NameSpace.ErrataVersion) == 0)) { + Status = InterpreterInstance->DestroyStructure ( + This, + RestJSonHeader + ); + break; + } + } + } + ThisSupportedRsrcTypeId ++; + } + return Status; +} + +/** + This function translates the given JSON text to JSON C Structure. + + @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. + @param[in] RsrcTypeIdentifier Resource type identifier. + @param[in] ResourceJsonText Given Restful resource. + @param[out] JsonStructure Property interpreted from given ResourceRaw. + + @retval EFI_SUCCESS + @retval Others. + +**/ +EFI_STATUS +EFIAPI +RestJsonStructureToStruct ( + IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, + IN EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *RsrcTypeIdentifier OPTIONAL, + IN CHAR8 *ResourceJsonText, + OUT EFI_REST_JSON_STRUCTURE_HEADER **JsonStructure +) +{ + EFI_STATUS Status; + REST_JSON_STRUCTURE_INSTANCE *Instance; + + if (This == NULL || + ResourceJsonText == NULL || + JsonStructure == NULL + ) { + return EFI_INVALID_PARAMETER; + } + + if (IsListEmpty (&mRestJsonStructureList)) { + return EFI_UNSUPPORTED; + } + Status = EFI_SUCCESS; + Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList); + while (TRUE) { + Status = InterpreterInstanceToStruct ( + This, + Instance, + RsrcTypeIdentifier, + ResourceJsonText, + JsonStructure + ); + if (!EFI_ERROR (Status)) { + break; + } + if (IsNodeAtEnd(&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) { + Status = EFI_UNSUPPORTED; + break; + } + Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); + }; + return Status; +} + +/** + This function destory REST property EFI structure which returned in + JsonToStructure(). + + @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. + @param[in] RestJSonHeader Property to destory. + + @retval EFI_SUCCESS + @retval Others + +**/ +EFI_STATUS +EFIAPI +RestJsonStructureDestroyStruct ( + IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, + IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader +) +{ + EFI_STATUS Status; + REST_JSON_STRUCTURE_INSTANCE *Instance; + + if (This == NULL || RestJSonHeader == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (IsListEmpty (&mRestJsonStructureList)) { + return EFI_UNSUPPORTED; + } + Status = EFI_SUCCESS; + Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList); + while (TRUE) { + Status = InterpreterInstanceDestoryJsonStruct ( + This, + Instance, + RestJSonHeader + ); + if (!EFI_ERROR (Status)) { + break; + } + if (IsNodeAtEnd(&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) { + Status = EFI_UNSUPPORTED; + break; + } + Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); + }; + return Status; +} + +/** + This function translates the given JSON C Structure to JSON text. + + @param[in] This EFI_REST_JSON_STRUCTURE_PROTOCOL instance. + @param[in] RestJSonHeader Given Restful resource. + @param[out] ResourceRaw Resource in RESTfuls service oriented. + + @retval EFI_SUCCESS + @retval Others Fail to remove the entry + +**/ +EFI_STATUS +EFIAPI +RestJsonStructureToJson ( + IN EFI_REST_JSON_STRUCTURE_PROTOCOL *This, + IN EFI_REST_JSON_STRUCTURE_HEADER *RestJSonHeader, + OUT CHAR8 **ResourceRaw +) +{ + EFI_STATUS Status; + REST_JSON_STRUCTURE_INSTANCE *Instance; + + if (This == NULL || RestJSonHeader == NULL || ResourceRaw == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (IsListEmpty (&mRestJsonStructureList)) { + return EFI_UNSUPPORTED; + } + Status = EFI_SUCCESS; + Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList); + while (TRUE) { + Status = InterpreterEfiStructToInstance ( + This, + Instance, + RestJSonHeader, + ResourceRaw + ); + if (!EFI_ERROR (Status)) { + break; + } + if (IsNodeAtEnd(&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) { + Status = EFI_UNSUPPORTED; + break; + } + Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); + }; + return Status; +} + +EFI_REST_JSON_STRUCTURE_PROTOCOL mRestJsonStructureProtocol = { + RestJsonStructureRegister, + RestJsonStructureToStruct, + RestJsonStructureToJson, + RestJsonStructureDestroyStruct +}; + +/** + This is the declaration of an EFI image entry point. + + @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 Others An unexpected error occurred. +**/ +//EFI_STATUS +//EFIAPI +//RestJsonStructureEntryPoint ( +// IN EFI_HANDLE ImageHandle, +// IN EFI_SYSTEM_TABLE *SystemTable +// ) +//{ +EFI_STATUS main(int argc, char** argv) +{ + EFI_HANDLE ImageHandle = (void*)argv[-2]; + IN EFI_SYSTEM_TABLE* SystemTable = (void*)argv[-1]; + EFI_STATUS Status; + + // + // CdePkg demo + // + if (1) { + extern CHAR8* gEfiCallerBaseName; + #define HUGESTRINGSIZE 65537 // buffer size 64kByte + 1 + char* pBuf = realloc(NULL, HUGESTRINGSIZE); // realloc() n/a in RedFish + int i; + + for (i = 0; i < argc; i++) // search upcase "/DEBUGBREAK" in arguments + if(0 == strcmp("/DEBUGBREAK", argv[i])) + __debugbreak(); + + for (i = 0; i < argc; i++) + printf("### CdePkg demo ### gEfiCallerBaseName: \"%s\" argv[%d] %s\n", gEfiCallerBaseName, i, argv[i]); + + for (i = 0; i < HUGESTRINGSIZE - 1; i++) + pBuf[i] = '0' + (char)(i % 32); + pBuf[i - 3] = '\0'; + strcat(pBuf, "\r\n"); + + printf("This is a very long string>>> %s\n<< %s\n", isfunc[i].szIsName, c, pBuffer)); + } + } + CDETRACE((TRCBAR(1) "\n")); + + } + } + + if (1/*TOfunctions*/) { + static struct { + wint_t(*tofunc)(win_t); + char* szToName; + }tofunc[] = { + {towlower, "towlower" }, + {towupper, "towupper" } + }; + + for (i = 0; i < sizeof(tofunc) / sizeof(tofunc[0]); i++) { + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "########################## Test %s() in\n", tofunc[i].szToName)); + CDETRACE((TRCINF(1) "##################################################################\n")); + + for (c = 0; c < count; c++) { + + result = tofunc[i].tofunc(c); + if (c != result) { + sprintf(pBuffer, "%s(0x%04X / %c) -> 0x%04X / %c", tofunc[i].szToName, c, c, result, result); + + + CDETRACE((TRCINF(1) "%s\n", pBuffer)); + } + } + CDETRACE((TRCBAR(1) "\n")); + + } + } + + if (1/*ISWCTYPE() and WCTYPE() function*/) { + wint_t t; + char* wctype_table[] = { "alpha","alnum","alpha","blank","cntrl","digit","graph","lower","print","punct","space","upper","xdigit","Xdigit" }; + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "########################## Test iswctype() and wctype() in \n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + + CDETRACE((TRCINF(1)"%04X %04X %s\n", 0x0157, _ALPHA | _BLANK | _PUNCT | _DIGIT | _LOWER | _UPPER, "print")); + CDETRACE((TRCINF(1)"%04X %04X %s\n", 0x0117, _ALPHA | _PUNCT | _DIGIT | _LOWER | _UPPER, "graph")); + CDETRACE((TRCINF(1)"%04X %04X %s\n", 0x0107, _ALPHA | _DIGIT | _LOWER | _UPPER, "alnum")); + CDETRACE((TRCINF(1)"%04X %04X %s\n", 0x0103, _ALPHA | _LOWER | _UPPER, "alpha")); + CDETRACE((TRCINF(1)"%04X %04X %s\n", 0x0001, _UPPER, "upper")); + CDETRACE((TRCINF(1)"%04X %04X %s\n", 0x0002, _LOWER, "lower")); + CDETRACE((TRCINF(1)"%04X %04X %s\n", 0x0004, _DIGIT, "digit")); + CDETRACE((TRCINF(1)"%04X %04X %s\n", 0x0008, _SPACE, "space")); + CDETRACE((TRCINF(1)"%04X %04X %s\n", 0x0010, _PUNCT, "punct")); + CDETRACE((TRCINF(1)"%04X %04X %s\n", 0x0020, _CONTROL, "cntrl")); + CDETRACE((TRCINF(1)"%04X %04X %s\n", 0x0040, _BLANK, "blank")); + CDETRACE((TRCINF(1)"%04X %04X %s\n", 0x0080, _HEX, "xdigit")); + + + for (t = 0; t < sizeof(wctype_table) / sizeof(wctype_table[0]); t++) { + CDETRACE((TRCINF(1) "########################## Testing \"%s\"\n", wctype_table[t])); + for (c = 0; c < count; c++) { + + result = iswctype((wint_t)c, wctype(wctype_table[t])); + + if (0 != result) { + sprintf(pBuffer, "%s%s%s%s%s%s%s%s%s", + (result & _UPPER) ? "_UPPER " : "", + (result & _LOWER) ? "_LOWER " : "", + (result & _DIGIT) ? "_DIGIT " : "", + (result & _SPACE) ? "_SPACE " : "", + (result & _PUNCT) ? "_PUNCT " : "", + (result & _CONTROL) ? "_CONTROL " : "", + (result & _BLANK) ? "_BLANK " : "", + (result & _ALPHA) ? "_ALPHA " : "", + (result & _HEX) ? "_HEX " : ""); + + CDETRACE((TRCINF(0 != result) /* <<< no comma >>> */ "iswctype(%04X, wctype(%s)) -> %s\n", c, wctype_table[t], pBuffer)); + } + + } + } + } + if (1/*WCTRANS and TOWCTRANS function*/) { + wint_t t, wc; + //int c; + static char* property_table[] = { { "toupper" },{"tolower" },{ "towupper" },{ "towlower" },{ "INVALID" } }; + + for (i = 0, t = 0; i < sizeof(property_table) / sizeof(property_table[0]); i++) { + + t = wctrans(property_table[i]); + + CDETRACE((TRCINF(1) " %s -> t == %X\n", property_table[i], t)); + + for (c = 0; c < count; c++) { + + wc = towctrans((wint_t)c, t); + + CDETRACE((TRCINF(wc != (wint_t)c) /* <<< no comma >>> */ "Character 0x%04X is converted to 0x%04X\n", c, wc)); + } + } + } + }//if(2) + + // + // demonstrating WCHAR.H tests + // + if (3) + { + int i; + wchar_t b[48]; + void* p; + UNIDUMPPARM hexparms = { .reg = 0, .bit.elmsizemin1 = 2 - 1, .bit.fBaseOfs = 0 }; + //getchar(); + //__debugbreak();// NOTE: to use breakpoints run DBGEMU.BAT + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "########################## CdePkg driver wcharhfunctions \n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + + CDETRACE((TRCFAT/*M-odule F-ile li-N-e FATAL (including termination)*/(0 == strncmp(argv[0], "unknownCdeDriver", strlen("unknownCdeDriver"))) "\nA command line is not injected into NVRAM (\"LoadOption.efi\") - driver terminated\n\n")); + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"int wprintf(const wchar_t * format, ...)\"\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"int swprintf(wchar_t * s, size_t n,const wchar_t * format, ...)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + + wprintf(L"%S(%d): Welcome, to the wide, wide jungle... \n", __FILE__, __LINE__); + wmemset(b, 'U' /*0x55*/, ELC(b)); // clear buffer + swprintf(&b[0], sizeof(b) / sizeof(b[0]), L"Welcome, to the wide, wide jungle... \n"); + CDETRACE((TRCINF(1) "\n")); + UniDump(hexparms, sizeof(b), (unsigned long long)& b[0], (unsigned long long(*)(unsigned long long))& GetMem8, WriteString); + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"int vswprintf(wchar_t* s, size_t n, const wchar_t* format, va_list arg)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + + wmemset(b, 'U' /*0x55*/, ELC(b)); // clear buffer + vswprintf(&b[0], sizeof(b) / sizeof(b[0]), L"WELCOME, TO the wide, wide jungle...\n", NULL); + CDETRACE((TRCINF(1) "\n")); + UniDump(hexparms, sizeof(b), (unsigned long long)& b[0], (unsigned long long(*)(unsigned long long))& GetMem8, WriteString); + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"wchar_t *wcscpy(wchar_t * s1,const wchar_t * s2)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + for (i = 0; i < 1 * sizeof(TWSTRING); i += 1) { + wmemset(b, 'U' /*0x55*/, ELC(b)); // clear buffer + p = wcscpy(&b[i], TWSTRING); + UniDump(hexparms, sizeof(b), (unsigned long long) & b[0], (unsigned long long(*)(unsigned long long)) & GetMem8, WriteString); + CDETRACE((TRCERR(p != &b[i]) "wrong pointer\n")); + } + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"wchar_t *wcsncpy(wchar_t * s1,const wchar_t * s2)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + for (i = 0; i < 1 * sizeof(TWSTRING); i += 1) { + wmemset(b, 'U' /*0x55*/, ELC(b)); // clear buffer + p = wcsncpy(&b[i], TWSTRING, sizeof(TWSTRING) - 3 * sizeof(wchar_t)); + UniDump(hexparms, sizeof(b), (unsigned long long) & b[0], (unsigned long long(*)(unsigned long long)) & GetMem8, WriteString); + CDETRACE((TRCERR(p != &b[i]) "wrong pointer\n")); + } + // __debugbreak(); + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"wchar_t* wcscat(wchar_t* s1, const wchar_t* s2)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + for (i = 0; i < 1 * sizeof(TWSTRING); i += 1) { + wmemset(b, 'U' /*0x55*/, ELC(b)); // clear buffer + p = wcscpy(&b[i], TWSTRING); + p = wcscat(&b[i], TWSTRING2); + UniDump(hexparms, sizeof(b), (unsigned long long) & b[0], (unsigned long long(*)(unsigned long long)) & GetMem8, WriteString); + CDETRACE((TRCERR(p != &b[i]) "wrong pointer\n")); + } + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"wchar_t *wcsncat(wchar_t * s1,const wchar_t * s2, size_t n)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + for (i = 0; i < 1 * sizeof(TWSTRING); i += 1) { + wmemset(b, 'U' /*0x55*/, ELC(b)); // clear buffer + p = wcscpy(&b[i], TWSTRING); + p = wcsncat(&b[i], TWSTRING2, 2 * sizeof(wchar_t)); + CDETRACE((TRCINF(1) "%S\n", b)); + UniDump(hexparms, sizeof(b), (unsigned long long) & b[0], (unsigned long long(*)(unsigned long long)) & GetMem8, WriteString); + CDETRACE((TRCERR(p != &b[i]) "wrong pointer\n")); + } + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"int wcscmp(const wchar_t *s1, const wchar_t *s2)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + for (i = 0; i < sizeof("UVWXYZ"); i++) { + int r = 0; + wchar_t string[] = { L"UVWXYZ" }; + wcscpy(string, L"UVWXYZ"); + string[i] = '\0'; // shift the termination \0 through the string + r = wcscmp(string, L"UVW"); + CDETRACE((TRCINF(1) "Strings L\"UVW\" and L\"%S\" %s\n", string, r == 0 ? "MATCH" : "do not match")); + } + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"int wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + for (i = 0; i < sizeof("UVWXYZ"); i++) { + int r = 0; + wchar_t string[] = { L"UVWxyz" }; + wcscpy(string, L"UVWxyz"); + r = wcsncmp(string, L"UVWXYZ", i); + CDETRACE((TRCINF(1) "First %d characters L\"UVWXYZ\" and L\"%S\" %s\n", i, string, r == 0 ? "MATCH" : "do not match")); + } + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### NOT yet implemented: \"size_t wcsxfrm(wchar_t * s1,const wchar_t * s2, size_t n)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"wchar_t* wcschr(const wchar_t* s, wchar_t c)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + if (1) { + static wchar_t pat[] = { 'a', '#', '$' }; + for (i = 0; i < ELC(pat); i++) { + wmemset(b, 'U' /*0x55*/, ELC(b)); + b[ELC(b) - 1] = L'\0'; // set termination '\0' at the end of the buffer + b[i] = (wchar_t)pat[i]; // place pattern in memory + p = wcschr(b, pat[i]); + CDETRACE((TRCINF(1) "Character '%C' found in buffer at offset %zd\n", pat[i], (wchar_t*)p - (wchar_t*)&b[0])); + } + //p = memchr(b, 'X', sizeof(b)); // search for 'X' that will not be found + //CDETRACE((TRCINF(p == NULL) "As expected character 'X' not found in buffer\n")); + //CDETRACE((TRCERR(p != NULL) "Character 'X' unexpectedly found\n")); + } + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"size_t wcscspn(const wchar_t* s1, const wchar_t* s2)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + if (1) { + static int pat[] = { 'c','G','9','#' }; + static wchar_t* set[] = { L"abc",L"DEFGH",L"123456789",L"ABC" }; + for (i = 0; i < ELC(pat); i++) { + size_t ofs; + wmemset(b, 'U' /*0x55*/, ELC(b)); + b[ELC(b) - 1] = '\0'; // set termination '\0' at the end of the buffer + b[i] = (wchar_t)pat[i]; // place pattern in memory + ofs = wcscspn(b, set[i]); + CDETRACE((TRCINF(ofs != wcslen(b)) "Character '%c' is member of set \"%S\" and found in the buffer at offset %zd\n", pat[i], set[i], ofs)); + CDETRACE((TRCINF(ofs == wcslen(b)) "Character '%c' is NOT member of set \"%S\" \n", pat[i], set[i])); + } + } + + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"wchar_t* wcspbrk(const wchar_t* s1, const wchar_t* s2)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + // sample taken from https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strpbrk-wcspbrk-mbspbrk-mbspbrk-l?view=vs-2019#example + if (1) { + wchar_t string[100] = L"The 3 men and 2 boys ate 5 pigs"; + wchar_t* result = NULL; + // Return pointer to first digit in "string". + CDETRACE((TRCINF(1) "1: %S\n", string)); + result = wcspbrk(string, L"0123456789"); + CDETRACE((TRCINF(1) "2: %S\n", result++)); + result = wcspbrk(result, L"0123456789"); + CDETRACE((TRCINF(1) "3: %S\n", result++)); + result = wcspbrk(result, L"0123456789"); + CDETRACE((TRCINF(1) "4: %S\n", result)); + } + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"wchar_t* wcsrchr(const wchar_t* s, wchar_t c)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + // sample taken from https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strchr-wcschr-mbschr-mbschr-l?view=vs-2019#example + if (1) { + wchar_t ch = 'r'; + + wchar_t string[] = L"The quick brown dog jumps over the lazy fox"; + wchar_t fmt1[] = L" 1 2 3 4 5"; + wchar_t fmt2[] = L"12345678901234567890123456789012345678901234567890"; + + wchar_t* pdest; + int result; + + CDETRACE((TRCINF(1) "String to be searched:\n")); + CDETRACE((TRCINF(1) "%S\n", string)); + CDETRACE((TRCINF(1) "%S\n", fmt1)); + CDETRACE((TRCINF(1) "%S\n", fmt2)); + CDETRACE((TRCINF(1) "Search char: %c\n", ch)); + + // Search forward. + pdest = wcschr(string, ch); + result = (int)(pdest - string + 1); + if (pdest != NULL) + CDETRACE((TRCINF(1) "Result: first %c found at position %d\n", ch, result)); + else + CDETRACE((TRCINF(1) "Result: %c not found\n", ch)); + + // Search backward. + pdest = wcsrchr(string, ch); + result = (int)(pdest - string + 1); + if (pdest != NULL) + CDETRACE((TRCINF(1) "Result: last %c found at position %d\n", ch, result)); + else + CDETRACE((TRCINF(1) "Result:\t%c not found\n", ch)); + } + + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"size_t wcsspn(const wchar_t* s1, const wchar_t* s2)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + // sample taken from https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strspn-wcsspn-mbsspn-mbsspn-l?view=vs-2019#example + if (1) { + wchar_t string[] = L"cabbage"; + size_t result; + // This program uses strspn to determine + // the length of the segment in the string "cabbage" + // consisting of a's, b's, and c's. In other words, + // it finds the first non-abc letter. + // + result = wcsspn(string, L"abc"); + CDETRACE((TRCINF(1) "The portion of '%S' containing only a, b, or c " "is %zd bytes long\n", string, result)); + } + + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"wchar_t* wcsstr(const wchar_t* s1, const wchar_t* s2)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + // sample taken from https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strstr-wcsstr-mbsstr-mbsstr-l?view=vs-2019#example + if (1) { + wchar_t str[] = L"lazy"; + wchar_t string[] = L"The quick brown dog jumps over the lazy fox"; + wchar_t fmt1[] = L" 1 2 3 4 5"; + wchar_t fmt2[] = L"12345678901234567890123456789012345678901234567890"; + + wchar_t* pdest; + int result; + + CDETRACE((TRCINF(1) "String to be searched:\n")); + CDETRACE((TRCINF(1) "%S\n", string)); + CDETRACE((TRCINF(1) "%S\n", fmt1)); + CDETRACE((TRCINF(1) "%S\n", fmt2)); + CDETRACE((TRCINF(1) "Search string: %S\n", str)); + + // Search forward. + pdest = wcsstr(string, str); + result = (int)(pdest - string + 1); + if (pdest != NULL) + CDETRACE((TRCINF(1) "Result: first \"%S\" found at position %d\n", str, result)); + else + CDETRACE((TRCINF(1) "Result: %S not found\n", str)); + } + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"wchar_t* wcstok(wchar_t* strToken, const wchar_t* strDelimit)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + // sample taken from https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtok-strtok-l-wcstok-wcstok-l-mbstok-mbstok-l?view=vs-2019#example + if (1) { + wchar_t string[] = L"A string?of ,,tokens!and some more tokens\n,!?"; + const wchar_t seps[] = L" ,!?\n"; + wchar_t* context; + wchar_t* token; + + CDETRACE((TRCINF(1) "String: %S", string)); + CDETRACE((TRCINF(1) "Tokens:\n")); + + // Establish string and get the first token: + //__debugbreak(); + token = wcstok(string, seps, &context); // C4996 + // Note: strtok is deprecated; consider using strtok_s instead + while (token != NULL) + { + // While there are tokens in "string" + CDETRACE((TRCINF(1) " \"%S\"\n", token)); + + // Get next token: + token = wcstok(NULL, seps, &context); // C4996 + } + } + + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"size_t wcslen(const wchar_t* s)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + if (1) { + static wchar_t string[] = L"The quick brown dog jumps over the lzy fox"; + + size_t len; + + len = wcslen(string); + CDETRACE((TRCINF(1) "What is the length of the wcString \"%S\"???\n", string)); + CDETRACE((TRCINF(1) "%zd!!! Answer to the Ultimate Question of Life, the Universe, and Everything...\n", len)); + + } + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + if (1) { + static wchar_t pat[] = { 'a','#','\0','$' }; + for (i = 0; i < ELC(pat); i++) { + wmemset(b, 'U' /*0x55*/, ELC(b)); + b[i] = (wchar_t)pat[i]; //place pattern in memory + p = wmemchr(b, pat[i], ELC(b)); + CDETRACE((TRCINF(1) "Character '%c' found in buffer at offset %zd\n", pat[i], (wchar_t*)p - (wchar_t*)&b[0])); + } + p = wmemchr(b, 'X', ELC(b)); // search for 'X' that will not be found + CDETRACE((TRCINF(p == NULL) "As expected character 'X' not found in buffer\n")); + CDETRACE((TRCERR(p != NULL) "Character 'X' unexpectedly found\n")); + } + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"int wmemcmp(const wchar_t *s1, const wchar_t *s2,size_t n)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "NOTE: A termination '\\0', 0x00 can probably not be displayed in a terminal program\n")); + for (i = 0; i < sizeof("ABCDEF"); i++) { + int r = 0; + r = wmemcmp(L"ABCDEF", L"ABCdef", i); + CDETRACE((TRCINF(1) "first %d charachters of \"ABCDEF\" and \"ABCdef\"%s match\n", i, r == 0 ? "" : " DO NOT")); + } + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"wchar_t *wmemcpy(wchar_t * s1,const wchar_t * s2, size_t n)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + for (i = 0; i < 1 * sizeof(TWSTRING); i += 1) { + wmemset(b, 'U' /*0x55*/, ELC(b)); + p = wmemcpy(&b[i], TWSTRING, ELC(TWSTRING) - 1/*skip termination \0 of the string literal*/); + CDETRACE((TRCINF(1) "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19], b[20], b[21], b[22], b[23], b[24], b[25], b[26], b[27], b[28], b[29], b[30], b[31], b[32], b[33], b[34], b[35], b[36], b[37], b[38], b[39], b[40], b[41], b[42], b[43], b[44], b[45], b[46], b[47])); + UniDump(hexparms, sizeof(b), (unsigned long long) & b[0], (unsigned long long(*)(unsigned long long)) & GetMem8, WriteString); + CDETRACE((TRCERR(p != &b[i]) "wrong pointer\n")); + } + + CDETRACE((TRCINF(1) "##################################################################\n")); + CDETRACE((TRCINF(1) "### Demonstrating \"wchar_t *wmemmove(wchar_t *s1, const wchar_t *s2,size_t n)\"\n")); + CDETRACE((TRCINF(1) "##################################################################\n")); + for (i = 0; i < ELC(b) - ELC(TWSTRING) + 2; i += 1) { + wmemset(b, 'U' /*0x55*/, ELC(b)); + wmemcpy(&b[i], TWSTRING, ELC(TWSTRING) - 1/*skip termination \0 of the string literal*/); + p = memmove(&b[ELC(b) / 2], &b[i], ELC(TWSTRING) - 1); + CDETRACE((TRCINF(1) "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19], b[20], b[21], b[22], b[23], b[24], b[25], b[26], b[27], b[28], b[29], b[30], b[31], b[32], b[33], b[34], b[35], b[36], b[37], b[38], b[39], b[40], b[41], b[42], b[43], b[44], b[45], b[46], b[47])); + UniDump(hexparms, sizeof(b), (unsigned long long) & b[0], (unsigned long long(*)(unsigned long long)) & GetMem8, WriteString); + CDETRACE((TRCERR(p != &b[ELC(b) / 2]) "wrong pointer\n")); + } + + }//if (3) + InitializeListHead (&mRestJsonStructureList); + // + // Install the Restful Resource Interpreter Protocol. + // + mProtocolHandle = NULL; + Status = gBS->InstallProtocolInterface ( + &mProtocolHandle, + &gEfiRestJsonStructureProtocolGuid, + EFI_NATIVE_INTERFACE, + (VOID *)&mRestJsonStructureProtocol + ); + return Status; +} + +/** + This is the unload handle for Redfish discover module. + + Disconnect the driver specified by ImageHandle from all the devices in the handle database. + Uninstall all the protocols installed in the driver entry point. + + @param[in] ImageHandle The drivers' driver image. + + @retval EFI_SUCCESS The image is unloaded. + @retval Others Failed to unload the image. + +**/ +EFI_STATUS +EFIAPI +RestJsonStructureUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + REST_JSON_STRUCTURE_INSTANCE *Instance; + REST_JSON_STRUCTURE_INSTANCE *NextInstance; + + Status = gBS->UninstallProtocolInterface ( + mProtocolHandle, + &gEfiRestJsonStructureProtocolGuid, + (VOID *)&mRestJsonStructureProtocol + ); + + if (IsListEmpty (&mRestJsonStructureList)) { + return Status; + } + // + // Free memory of REST_JSON_STRUCTURE_INSTANCE instance. + // + Instance = (REST_JSON_STRUCTURE_INSTANCE *)GetFirstNode (&mRestJsonStructureList); + do { + NextInstance = NULL; + if (!IsNodeAtEnd(&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance)) { + NextInstance = (REST_JSON_STRUCTURE_INSTANCE *)GetNextNode (&mRestJsonStructureList, &Instance->NextRestJsonStructureInstance); + } + FreePool ((VOID *)Instance); + Instance = NextInstance; + } while (Instance != NULL); + + return Status; +} + +///////////////////////////////////////////////////////////////////////////// +/// UNIDUMP for debug purpose only ////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +/*! + @fn unsigned long long GetMem8(void *pAddr) + + @brief read a BYTE from a given memory location + + @details + + @param[in] *pAddr + + @return byte read +*/ +unsigned long long GetMem8(void* pAddr) +{ + unsigned char nRet, * p = (unsigned char*)pAddr; + nRet = 0xFF & *p; + return nRet; + +} + +/*! + @fn static unsigned WriteString(IN char *pszLineOfText) + + @brief print a text line + + @details + + @param[in] *pszLineOfText : pointer to ZERO terminated text line + + @return 0 +*/ +unsigned WriteString(char* pszLineOfText) +{ + + CDETRACE((TRCBAR(1) "%s", pszLineOfText)); + + return 0; +}; + +/*! +@copyright + + Copyright (c) 2020, Kilian Kegel. All rights reserved. + This program and the accompanying materials are licensed and made + available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license + may be found at + + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +@file _UniDump.c + +@brief + This module implements the universal dump routine +@todo + implement pitch support +*/ +static const char szTwoSpaces[] = { 0x20,'\0' }; +static const char szOneSpace[] = { 0x20,'\0' }; + +/*! + @fn static int PrintAscii(char *pBuffer, unsigned elmsize, unsigned cToPrint,unsigned char *pTextLineBuf) + + @brief prints the ASCII interpretation binary byte/word/dword/qword + + @details Features: + + @param[in] *pBuffer : pointer to binary buffer + @param[in] elmsize : element size + @param[in] cToPrint : count to print + @param[in] *pTextLineBuf : pointer to text buffer + + @return 0 +*/ +static int PrintAscii(char* pBuffer, unsigned elmsize, unsigned cToPrint, char* pTextLineBuf) { + unsigned char* pb = (unsigned char*)&pBuffer[0]; + unsigned short* pw = (unsigned short*)&pBuffer[0]; + unsigned int* pdw = (unsigned int*)&pBuffer[0]; + unsigned long long* pqw = (unsigned long long*) & pBuffer[0]; + unsigned long long qwLit2Big;/*!< little endian to big endian translation buffer*/ + unsigned char* pLit2Big = (unsigned char*)&qwLit2Big; + unsigned j; + +#define PRINTREVERSE for (k = elmsize - 1 ; k != (unsigned)-1 ; k--){\ + sprintf(&pTextLineBuf[strlen(pTextLineBuf)],"%c", isalnum(pLit2Big[k]) ? 0xFF & pLit2Big[k] : '.'); \ + }\ + if (elmsize - 1){/*!< add space between ASCII char, except in 8-bit format*/\ + sprintf(&pTextLineBuf[strlen(pTextLineBuf)]," ");\ + }// END PRINTREVERSE + + switch (elmsize) { + unsigned k; + case sizeof(char) : + for (j = 0; j < cToPrint; j += elmsize) { + *((unsigned char*)pLit2Big) = 0xFF & pb[j / elmsize]; + PRINTREVERSE; + } + break; + + case sizeof(short) : + for (j = 0; j < cToPrint; j += elmsize) { + *((unsigned short*)pLit2Big) = 0xFFFF & pw[j / elmsize]; + PRINTREVERSE; + } + break; + + case sizeof(int) : + for (j = 0; j < cToPrint; j += elmsize) { + *((unsigned int*)pLit2Big) = 0xFFFFFFFF & pdw[j / elmsize]; + PRINTREVERSE; + } + break; + + case sizeof(long long) : + for (j = 0; j < cToPrint; j += elmsize) { + *((unsigned long long*)pLit2Big) = 0xFFFFFFFFFFFFFFFFLL & pqw[j / elmsize]; + PRINTREVERSE; + } + break; + } + return 0; +} + +/*! + @fn int UniDump(UNIDUMPPARM ctrl, unsigned elmcount, unsigned long long startaddr, unsigned long long(*pfnGetElm)(unsigned long long qwAddr),unsigned (*pfnWriteStr)(char *szLine)) + + @brief dump an addressrange, highly configurable + + @details Features: + 1. w/ or w/o appended ASCII translation -> UNIDUMPPARM.bit.fNoAscii + 2. byte/word/dword and qword support -> UNIDUMPPARM.bit.elmsize + 3. configurable/enabe/disable address size printed at begin of each line -> UNIDUMPPARM.bit.nAddrSize + 4. configurable bytes per lane + 1, until 128 -> UNIDUMPPARM.bit.nBytesPerLine + 5. configurable base and offset only print -> UNIDUMPPARM.bit.fBaseOfs + 6. configurable dash character "-" at half of the line -> UNIDUMPPARM.bit.fNoDash + 7. configurable pitch to next character -> UNIDUMPPARM.bit.pitch + + @param[in] ctrl : control word + @param[in] elmcount : element count + @param[in] startaddr : start address + @param[in] pfnGetElm : get element routine + @param[in] pfnWriteStr : call back routine to print a string + + @return 0 +*/ +int UniDump(UNIDUMPPARM ctrl, unsigned elmcount, unsigned long long startaddr, unsigned long long(*pfnGetElm)(unsigned long long qwAddr), unsigned (*pfnWriteStr)(char* szLine)) +{ + + unsigned elmsize = 1 + ctrl.bit.elmsizemin1; + unsigned u/* nLineLengthHalf ? 0 : 2);/*count dash and space 0 / 2, depending on HEXDUMPPARMS.bit.fNoDash*/ + + + if (0 != rem && 1 == ctrl.bit.fNoAscii) + sprintf(&pTextLineBuf[strlen(pTextLineBuf)], "\n"); + + if (0 == ctrl.bit.fNoAscii) { + if (rem) { + unsigned x; + for (x = 0; x < cSpaces + cDashSpace; x++) { + sprintf(&pTextLineBuf[strlen(pTextLineBuf)], szOneSpace); + } + sprintf(&pTextLineBuf[strlen(pTextLineBuf)], szTwoSpaces); + } + + PrintAscii(&pBuffer[0], elmsize, rem, &pTextLineBuf[strlen(pTextLineBuf)]); + + sprintf(&pTextLineBuf[strlen(pTextLineBuf)], "\n"); + pfnWriteStr(pTextLineBuf); + pTextLineBuf[0] = '\0'; + } + } + + free(pTextLineBuf); + free(pBuffer); + + return 0; +} diff --git a/CdeEmuPkg/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.inf b/CdeEmuPkg/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.inf new file mode 100644 index 00000000000..ff3ac2edca4 --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.inf @@ -0,0 +1,49 @@ +## @file +# Implementation of EFI REST JSON Structure Protocol. +# +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = RestJsonStructureDxe + FILE_GUID = 83FAAFBF-FC4B-469F-892A-798E66A6F50A + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + #ENTRY_POINT = RestJsonStructureEntryPoint + ENTRY_POINT = _MainEntryPointDxe + IMAGE_ENTRY_POINT = _cdeCRT0UefiDxeEDK + UNLOAD_IMAGE = RestJsonStructureUnload + +[Packages] + CdePkg/CdePkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + +[Sources] + RestJsonStructureDxe.c + RestJsonStructureInternal.h + +[LibraryClasses] + BaseLib + BaseMemoryLib + MemoryAllocationLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiLib + CdeLib + RedfishCrtLib + DebugLib + +[Protocols] + gEfiRestJsonStructureProtocolGuid ## Producing + +[Depex] + TRUE + AND gCdeDxeProtocolGuid + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS = /GL- /wd4189 /O1 /Fa /Zc:wchar_t- +# MSFT:*_*_*_DLINK_FLAGS = /verbose \ No newline at end of file diff --git a/CdeEmuPkg/RedfishPkg/RestJsonStructureDxe/RestJsonStructureInternal.h b/CdeEmuPkg/RedfishPkg/RestJsonStructureDxe/RestJsonStructureInternal.h new file mode 100644 index 00000000000..e1394cfd36d --- /dev/null +++ b/CdeEmuPkg/RedfishPkg/RestJsonStructureDxe/RestJsonStructureInternal.h @@ -0,0 +1,33 @@ +/** @file + The internal definitions of EFI REST Resource JSON to C structure convertor + Protocol. + + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef EFI_REST_JSON_STRUCTURE_INTERNAL_H_ +#define EFI_REST_JSON_STRUCTURE_INTERNAL_H_ + +#include +#include +#include +#include +#include +#include + +/// +/// Internal structure to maintain the information of JSON to +/// C structure convertor. +/// +typedef struct _REST_JSON_STRUCTURE_INSTANCE { + LIST_ENTRY NextRestJsonStructureInstance; ///< Next convertor instance + UINTN NumberOfNameSpaceToConvert; ///< Number of resource type this convertor supports. + EFI_REST_JSON_RESOURCE_TYPE_IDENTIFIER *SupportedRsrcIndentifier; ///< The resource type linklist + EFI_REST_JSON_STRUCTURE_TO_STRUCTURE JsonToStructure; ///< JSON to C structure function + EFI_REST_JSON_STRUCTURE_TO_JSON StructureToJson; ///< C structure to JSON function + EFI_REST_JSON_STRUCTURE_DESTORY_STRUCTURE DestroyStructure; ///< Destory C struture function. +} REST_JSON_STRUCTURE_INSTANCE; +#endif diff --git a/CdeEmuPkg/Win/Host/WinHost.c b/CdeEmuPkg/Win/Host/WinHost.c new file mode 100644 index 00000000000..ed35e2c7e38 --- /dev/null +++ b/CdeEmuPkg/Win/Host/WinHost.c @@ -0,0 +1,1129 @@ +/**@file + WinNt emulator of pre-SEC phase. It's really a Win32 application, but this is + Ok since all the other modules for NT32 are NOT Win32 applications. + + This program gets NT32 PCD setting and figures out what the memory layout + will be, how may FD's will be loaded and also what the boot mode is. + + This code produces 128 K of temporary memory for the SEC stack by directly + allocate memory space with ReadWrite and Execute attribute. + +Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP
+SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include "WinHost.h" + +#ifndef SE_TIME_ZONE_NAME +#define SE_TIME_ZONE_NAME TEXT("SeTimeZonePrivilege") +#endif + +// +// The growth size for array of module handle entries +// +#define MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE 0x100 + +// +// Module handle entry structure +// +typedef struct { + CHAR8 *PdbPointer; + VOID *ModHandle; +} PDB_NAME_TO_MOD_HANDLE; + +// +// An Array to hold the module handles +// +PDB_NAME_TO_MOD_HANDLE *mPdbNameModHandleArray = NULL; +UINTN mPdbNameModHandleArraySize = 0; + +// +// Default information about where the FD is located. +// This array gets filled in with information from PcdWinNtFirmwareVolume +// The number of array elements is allocated base on parsing +// PcdWinNtFirmwareVolume and the memory is never freed. +// +UINTN gFdInfoCount = 0; +NT_FD_INFO *gFdInfo; + +// +// Array that supports seperate memory rantes. +// The memory ranges are set by PcdWinNtMemorySizeForSecMain. +// The number of array elements is allocated base on parsing +// PcdWinNtMemorySizeForSecMain value and the memory is never freed. +// +UINTN gSystemMemoryCount = 0; +NT_SYSTEM_MEMORY *gSystemMemory; + +/*++ + +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. + It uses gSystemMemory[] and gSystemMemoryCount that were created by + parsing the host environment variable EFI_MEMORY_SIZE. + The size comes from the varaible and the address comes from the call to + UnixOpenFile. + +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 + +**/ +EFI_STATUS +WinPeiAutoScan ( + IN UINTN Index, + OUT EFI_PHYSICAL_ADDRESS *MemoryBase, + OUT UINT64 *MemorySize + ) +{ + if (Index >= gSystemMemoryCount) { + return EFI_UNSUPPORTED; + } + + // + // Allocate enough memory space for emulator + // + gSystemMemory[Index].Memory = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (gSystemMemory[Index].Size), MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (gSystemMemory[Index].Memory == 0) { + return EFI_OUT_OF_RESOURCES; + } + + *MemoryBase = gSystemMemory[Index].Memory; + *MemorySize = gSystemMemory[Index].Size; + + return EFI_SUCCESS; +} + +/*++ + +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 + +**/ +EFI_STATUS +WinFdAddress ( + IN UINTN Index, + IN OUT EFI_PHYSICAL_ADDRESS *FdBase, + IN OUT UINT64 *FdSize, + IN OUT EFI_PHYSICAL_ADDRESS *FixUp + ) +{ + if (Index >= gFdInfoCount) { + return EFI_UNSUPPORTED; + } + + + *FdBase = (EFI_PHYSICAL_ADDRESS)(UINTN)gFdInfo[Index].Address; + *FdSize = (UINT64)gFdInfo[Index].Size; + *FixUp = 0; + + if (*FdBase == 0 && *FdSize == 0) { + return EFI_UNSUPPORTED; + } + + if (Index == 0) { + // + // FD 0 has XIP code and well known PCD values + // If the memory buffer could not be allocated at the FD build address + // the Fixup is the difference. + // + *FixUp = *FdBase - PcdGet64 (PcdEmuFdBaseAddress); + } + + return EFI_SUCCESS; +} + +/*++ + +Routine Description: + Since the SEC is the only Unix program in stack it must export + an interface to do POSIX calls. gUnix is initialized in UnixThunk.c. + +Arguments: + InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL); + InterfaceBase - Address of the gUnix global + +Returns: + EFI_SUCCESS - Data returned + +**/ +VOID * +WinThunk ( + VOID + ) +{ + return &gEmuThunkProtocol; +} + + +EMU_THUNK_PPI mSecEmuThunkPpi = { + WinPeiAutoScan, + WinFdAddress, + WinThunk +}; + +VOID +SecPrint ( + CHAR8 *Format, + ... + ) +{ + va_list Marker; + UINTN CharCount; + CHAR8 Buffer[0x1000]; + + va_start (Marker, Format); + + _vsnprintf (Buffer, sizeof (Buffer), Format, Marker); + + va_end (Marker); + + CharCount = strlen (Buffer); + WriteFile ( + GetStdHandle (STD_OUTPUT_HANDLE), + Buffer, + (DWORD)CharCount, + (LPDWORD)&CharCount, + NULL + ); +} + +/*++ + +Routine Description: + Check to see if an address range is in the EFI GCD memory map. + + This is all of GCD for system memory passed to DXE Core. FV + mapping and other device mapped into system memory are not + inlcuded in the check. + +Arguments: + Index - Which memory region to use + MemoryBase - Return Base address of memory region + MemorySize - Return size in bytes of the memory region + +Returns: + TRUE - Address is in the EFI GCD memory map + FALSE - Address is NOT in memory map + +**/ +BOOLEAN +EfiSystemMemoryRange ( + IN VOID *MemoryAddress + ) +{ + UINTN Index; + EFI_PHYSICAL_ADDRESS MemoryBase; + + MemoryBase = (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryAddress; + for (Index = 0; Index < gSystemMemoryCount; Index++) { + if ((MemoryBase >= gSystemMemory[Index].Memory) && + (MemoryBase < (gSystemMemory[Index].Memory + gSystemMemory[Index].Size)) ) { + return TRUE; + } + } + + return FALSE; +} + + +EFI_STATUS +WinNtOpenFile ( + IN CHAR16 *FileName, OPTIONAL + IN UINT32 MapSize, + IN DWORD CreationDisposition, + IN OUT VOID **BaseAddress, + OUT UINTN *Length + ) +/*++ + +Routine Description: + Opens and memory maps a file using WinNt services. If *BaseAddress is non zero + the process will try and allocate the memory starting at BaseAddress. + +Arguments: + FileName - The name of the file to open and map + MapSize - The amount of the file to map in bytes + CreationDisposition - The flags to pass to CreateFile(). Use to create new files for + memory emulation, and exiting files for firmware volume emulation + BaseAddress - The base address of the mapped file in the user address space. + If *BaseAddress is 0, the new memory region is used. + If *BaseAddress is not 0, the request memory region is used for + the mapping of the file into the process space. + Length - The size of the mapped region in bytes + +Returns: + EFI_SUCCESS - The file was opened and mapped. + EFI_NOT_FOUND - FileName was not found in the current directory + EFI_DEVICE_ERROR - An error occured attempting to map the opened file + +--*/ +{ + HANDLE NtFileHandle; + HANDLE NtMapHandle; + VOID *VirtualAddress; + UINTN FileSize; + + // + // Use Win API to open/create a file + // + NtFileHandle = INVALID_HANDLE_VALUE; + if (FileName != NULL) { + NtFileHandle = CreateFile ( + FileName, + GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE, + FILE_SHARE_READ, + NULL, + CreationDisposition, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + if (NtFileHandle == INVALID_HANDLE_VALUE) { + return EFI_NOT_FOUND; + } + } + // + // Map the open file into a memory range + // + NtMapHandle = CreateFileMapping ( + NtFileHandle, + NULL, + PAGE_EXECUTE_READWRITE, + 0, + MapSize, + NULL + ); + if (NtMapHandle == NULL) { + return EFI_DEVICE_ERROR; + } + // + // Get the virtual address (address in the emulator) of the mapped file + // + VirtualAddress = MapViewOfFileEx ( + NtMapHandle, + FILE_MAP_EXECUTE | FILE_MAP_ALL_ACCESS, + 0, + 0, + MapSize, + *BaseAddress + ); + if (VirtualAddress == NULL) { + return EFI_DEVICE_ERROR; + } + + if (MapSize == 0) { + // + // Seek to the end of the file to figure out the true file size. + // + FileSize = SetFilePointer ( + NtFileHandle, + 0, + NULL, + FILE_END + ); + if (FileSize == -1) { + return EFI_DEVICE_ERROR; + } + + *Length = FileSize; + } else { + *Length = MapSize; + } + + *BaseAddress = VirtualAddress; + + return EFI_SUCCESS; +} + +INTN +EFIAPI +main ( + IN INT Argc, + IN CHAR8 **Argv, + IN CHAR8 **Envp + ) +/*++ + +Routine Description: + Main entry point to SEC for WinNt. This is a Windows program + +Arguments: + Argc - Number of command line arguments + Argv - Array of command line argument strings + Envp - Array of environment variable strings + +Returns: + 0 - Normal exit + 1 - Abnormal exit + +--*/ +{ + EFI_STATUS Status; + HANDLE Token; + TOKEN_PRIVILEGES TokenPrivileges; + VOID *TemporaryRam; + UINT32 TemporaryRamSize; + VOID *EmuMagicPage; + UINTN Index; + UINTN Index1; + CHAR16 *FileName; + CHAR16 *FileNamePtr; + BOOLEAN Done; + EFI_PEI_FILE_HANDLE FileHandle; + VOID *SecFile; + CHAR16 *MemorySizeStr; + CHAR16 *FirmwareVolumesStr; + UINTN ProcessAffinityMask; + UINTN SystemAffinityMask; + INT32 LowBit; + + // + // Enable the privilege so that RTC driver can successfully run SetTime() + // + OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &Token); + if (LookupPrivilegeValue(NULL, SE_TIME_ZONE_NAME, &TokenPrivileges.Privileges[0].Luid)) { + TokenPrivileges.PrivilegeCount = 1; + TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + AdjustTokenPrivileges(Token, FALSE, &TokenPrivileges, 0, (PTOKEN_PRIVILEGES) NULL, 0); + } + + MemorySizeStr = (CHAR16 *) PcdGetPtr (PcdEmuMemorySize); + FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdEmuFirmwareVolume); + + SecPrint ("\n\rEDK II WIN Host Emulation Environment from http://www.tianocore.org/edk2/\n\r"); + if (1) { + int i; + char* pWorkspace = getenv("WORKSPACE"); + SecPrint ("######################################################################################################\n"); + SecPrint ("add \"/debug\" command line switch, to connect to the debugger at the very beginning of POST emulation\n"); + SecPrint ("######################################################################################################\n"); + + if (NULL == pWorkspace) + pWorkspace = ""; + if (Argc > 1) { + for (i = 1; i < Argc; i++) { + if (0 == strncmp("/debug", Argv[i],strlen("/debug"))) { + //SecPrint("IF YOU WANT TO DEBUG from the very beginning of the EMULATION:\n\t1. start the TASKMGR\n\t2. connect WinHost.exe to the debugger\n\t3. and press ENTER in this command box\nOR\n"); + SecPrint("\t1. start your debug engine (VS2022)\n"); + SecPrint("\t2. attach to process WinHost.exe in your SystemDebugger (Ctrl+Alt+P in VS2022)\n"); + SecPrint("\t4. SET A SOFTWARE BREAKPOINT (F9) in %s\\overrides\\EmulatorPkg\\Win\\Host\\WinHost.c line 448\n",pWorkspace); + SecPrint("\t5. and press ENTER in the WinHost command box\n"); + SecPrint("\t6. go back to the debug engine and RUN/SINGLE STEP the application\n"); + SecPrint("\t7. otherwise press enter to continue...\n"); + + getchar(); //wait for keyboard input + if (0 == strcmp("/debugbreak", Argv[i])) { + __debugbreak(); + } + + SecPrint("");//now you can single step the entire boot/emulation process, good luck... + } + } + } + } + // + // Determine the first thread available to this process. + // + // + // Determine the first thread available to this process. + // + if (GetProcessAffinityMask (GetCurrentProcess (), &ProcessAffinityMask, &SystemAffinityMask)) { + LowBit = (INT32)LowBitSet32 ((UINT32)ProcessAffinityMask); + if (LowBit != -1) { + // + // Force the system to bind the process to a single thread to work + // around odd semaphore type crashes. + // + SetProcessAffinityMask (GetCurrentProcess (), (INTN)(BIT0 << LowBit)); + } + } + + // + // Make some Windows calls to Set the process to the highest priority in the + // idle class. We need this to have good performance. + // + SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS); + SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST); + + SecInitializeThunk (); + // + // PPIs pased into PEI_CORE + // + AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI, &gEmuThunkPpiGuid, &mSecEmuThunkPpi); + + // + // Emulator Bus Driver Thunks + // + AddThunkProtocol (&mWinNtWndThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuGop), TRUE); + AddThunkProtocol (&mWinNtFileSystemThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuFileSystem), TRUE); + AddThunkProtocol (&mWinNtBlockIoThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuVirtualDisk), TRUE); + AddThunkProtocol (&mWinNtSnpThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuNetworkInterface), TRUE); + + // + // Allocate space for gSystemMemory Array + // + gSystemMemoryCount = CountSeparatorsInString (MemorySizeStr, '!') + 1; + gSystemMemory = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY)); + if (gSystemMemory == NULL) { + SecPrint ("ERROR : Can not allocate memory for %S. Exiting.\n\r", MemorySizeStr); + exit (1); + } + + // + // Allocate space for gSystemMemory Array + // + gFdInfoCount = CountSeparatorsInString (FirmwareVolumesStr, '!') + 1; + gFdInfo = calloc (gFdInfoCount, sizeof (NT_FD_INFO)); + if (gFdInfo == NULL) { + SecPrint ("ERROR : Can not allocate memory for %S. Exiting.\n\r", FirmwareVolumesStr); + exit (1); + } + // + // Setup Boot Mode. + // + SecPrint (" BootMode 0x%02x\n\r", PcdGet32 (PcdEmuBootMode)); + + // + // Allocate 128K memory to emulate temp memory for PEI. + // on a real platform this would be SRAM, or using the cache as RAM. + // Set TemporaryRam to zero so WinNtOpenFile will allocate a new mapping + // + TemporaryRamSize = TEMPORARY_RAM_SIZE; + TemporaryRam = VirtualAlloc (NULL, (SIZE_T) (TemporaryRamSize), MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (TemporaryRam == NULL) { + SecPrint ("ERROR : Can not allocate enough space for SecStack\n\r"); + exit (1); + } + SetMem32 (TemporaryRam, TemporaryRamSize, PcdGet32 (PcdInitValueInTempStack)); + + SecPrint (" OS Emulator passing in %u KB of temp RAM at 0x%08lx to SEC\n\r", + TemporaryRamSize / SIZE_1KB, + TemporaryRam + ); + + // + // If enabled use the magic page to communicate between modules + // This replaces the PI PeiServicesTable pointer mechanism that + // deos not work in the emulator. It also allows the removal of + // writable globals from SEC, PEI_CORE (libraries), PEIMs + // + EmuMagicPage = (VOID *)(UINTN)(FixedPcdGet64 (PcdPeiServicesTablePage) & MAX_UINTN); + if (EmuMagicPage != NULL) { + UINT64 Size; + Status = WinNtOpenFile ( + NULL, + SIZE_4KB, + 0, + &EmuMagicPage, + &Size + ); + if (EFI_ERROR (Status)) { + SecPrint ("ERROR : Could not allocate PeiServicesTablePage @ %p\n\r", EmuMagicPage); + return EFI_DEVICE_ERROR; + } + } + + // + // Open All the firmware volumes and remember the info in the gFdInfo global + // Meanwhile, find the SEC Core. + // + FileNamePtr = AllocateCopyPool (StrSize (FirmwareVolumesStr), FirmwareVolumesStr); + if (FileNamePtr == NULL) { + SecPrint ("ERROR : Can not allocate memory for firmware volume string\n\r"); + exit (1); + } + + for (Done = FALSE, Index = 0, SecFile = NULL; !Done; Index++) { + FileName = FileNamePtr; + for (Index1 = 0; (FileNamePtr[Index1] != '!') && (FileNamePtr[Index1] != 0); Index1++) + ; + if (FileNamePtr[Index1] == 0) { + Done = TRUE; + } else { + FileNamePtr[Index1] = '\0'; + FileNamePtr = &FileNamePtr[Index1 + 1]; + } + + // + // Open the FD and remember where it got mapped into our processes address space + // + Status = WinNtOpenFile ( + FileName, + 0, + OPEN_EXISTING, + &gFdInfo[Index].Address, + &gFdInfo[Index].Size + ); + if (EFI_ERROR (Status)) { + SecPrint ("ERROR : Can not open Firmware Device File %S (0x%X). Exiting.\n\r", FileName, Status); + exit (1); + } + + SecPrint (" FD loaded from %S", FileName); + + if (SecFile == NULL) { + // + // Assume the beginning of the FD is an FV and look for the SEC Core. + // Load the first one we find. + // + FileHandle = NULL; + Status = PeiServicesFfsFindNextFile ( + EFI_FV_FILETYPE_SECURITY_CORE, + (EFI_PEI_FV_HANDLE)gFdInfo[Index].Address, + &FileHandle + ); + if (!EFI_ERROR (Status)) { + Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SecFile); + if (!EFI_ERROR (Status)) { + SecPrint (" contains SEC Core"); + } + } + } + + SecPrint ("\n\r"); + } + // + // Calculate memory regions and store the information in the gSystemMemory + // global for later use. The autosizing code will use this data to + // map this memory into the SEC process memory space. + // + for (Index = 0, Done = FALSE; !Done; Index++) { + // + // Save the size of the memory and make a Unicode filename SystemMemory00, ... + // + gSystemMemory[Index].Size = _wtoi (MemorySizeStr) * SIZE_1MB; + + // + // Find the next region + // + for (Index1 = 0; MemorySizeStr[Index1] != '!' && MemorySizeStr[Index1] != 0; Index1++) + ; + if (MemorySizeStr[Index1] == 0) { + Done = TRUE; + } + + MemorySizeStr = MemorySizeStr + Index1 + 1; + } + + SecPrint ("\n\r"); + + // + // Hand off to SEC Core + // + SecLoadSecCore ((UINTN)TemporaryRam, TemporaryRamSize, gFdInfo[0].Address, gFdInfo[0].Size, SecFile); + + // + // If we get here, then the SEC Core returned. This is an error as SEC should + // always hand off to PEI Core and then on to DXE Core. + // + SecPrint ("ERROR : SEC returned\n\r"); + exit (1); +} + +VOID +SecLoadSecCore ( + IN UINTN TemporaryRam, + IN UINTN TemporaryRamSize, + IN VOID *BootFirmwareVolumeBase, + IN UINTN BootFirmwareVolumeSize, + IN VOID *SecCorePe32File + ) +/*++ + +Routine Description: + This is the service to load the SEC Core from the Firmware Volume + +Arguments: + TemporaryRam - Memory to use for SEC. + TemporaryRamSize - Size of Memory to use for SEC + BootFirmwareVolumeBase - Start of the Boot FV + SecCorePe32File - SEC Core PE32 + +Returns: + Success means control is transfered and thus we should never return + +--*/ +{ + EFI_STATUS Status; + VOID *TopOfStack; + VOID *SecCoreEntryPoint; + EFI_SEC_PEI_HAND_OFF *SecCoreData; + UINTN SecStackSize; + + // + // Compute Top Of Memory for Stack and PEI Core Allocations + // + SecStackSize = TemporaryRamSize >> 1; + + // + // |-----------| <---- TemporaryRamBase + TemporaryRamSize + // | Heap | + // | | + // |-----------| <---- StackBase / PeiTemporaryMemoryBase + // | | + // | Stack | + // |-----------| <---- TemporaryRamBase + // + TopOfStack = (VOID *)(TemporaryRam + SecStackSize); + + // + // Reservet space for storing PeiCore's parament in stack. + // + TopOfStack = (VOID *)((UINTN)TopOfStack - sizeof (EFI_SEC_PEI_HAND_OFF) - CPU_STACK_ALIGNMENT); + TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT); + + // + // Bind this information into the SEC hand-off state + // + SecCoreData = (EFI_SEC_PEI_HAND_OFF*)(UINTN)TopOfStack; + SecCoreData->DataSize = sizeof (EFI_SEC_PEI_HAND_OFF); + SecCoreData->BootFirmwareVolumeBase = BootFirmwareVolumeBase; + SecCoreData->BootFirmwareVolumeSize = BootFirmwareVolumeSize; + SecCoreData->TemporaryRamBase = (VOID*)TemporaryRam; + SecCoreData->TemporaryRamSize = TemporaryRamSize; + SecCoreData->StackBase = SecCoreData->TemporaryRamBase; + SecCoreData->StackSize = SecStackSize; + SecCoreData->PeiTemporaryRamBase = (VOID*) ((UINTN) SecCoreData->TemporaryRamBase + SecStackSize); + SecCoreData->PeiTemporaryRamSize = TemporaryRamSize - SecStackSize; + + // + // Load the PEI Core from a Firmware Volume + // + Status = SecPeCoffGetEntryPoint ( + SecCorePe32File, + &SecCoreEntryPoint + ); + if (EFI_ERROR (Status)) { + return ; + } + + // + // Transfer control to the SEC Core + // + SwitchStack ( + (SWITCH_STACK_ENTRY_POINT)(UINTN)SecCoreEntryPoint, + SecCoreData, + GetThunkPpiList (), + TopOfStack + ); + // + // If we get here, then the SEC Core returned. This is an error + // + return ; +} + +RETURN_STATUS +EFIAPI +SecPeCoffGetEntryPoint ( + IN VOID *Pe32Data, + IN OUT VOID **EntryPoint + ) +{ + EFI_STATUS Status; + PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; + + ZeroMem (&ImageContext, sizeof (ImageContext)); + ImageContext.Handle = Pe32Data; + + ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) SecImageRead; + + Status = PeCoffLoaderGetImageInfo (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + // + // Allocate space in NT (not emulator) memory with ReadWrite and Execute attribute. + // Extra space is for alignment + // + ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (ImageContext.ImageSize + (ImageContext.SectionAlignment * 2)), MEM_COMMIT, PAGE_EXECUTE_READWRITE); + if (ImageContext.ImageAddress == 0) { + return EFI_OUT_OF_RESOURCES; + } + // + // Align buffer on section boundary + // + ImageContext.ImageAddress += ImageContext.SectionAlignment - 1; + ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1); + + Status = PeCoffLoaderLoadImage (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = PeCoffLoaderRelocateImage (&ImageContext); + if (EFI_ERROR (Status)) { + return Status; + } + + *EntryPoint = (VOID *)(UINTN)ImageContext.EntryPoint; + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +SecImageRead ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN OUT UINTN *ReadSize, + OUT VOID *Buffer + ) +/*++ + +Routine Description: + Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file + +Arguments: + FileHandle - The handle to the PE/COFF file + FileOffset - The offset, in bytes, into the file to read + ReadSize - The number of bytes to read from the file starting at FileOffset + Buffer - A pointer to the buffer to read the data into. + +Returns: + EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset + +--*/ +{ + CHAR8 *Destination8; + CHAR8 *Source8; + UINTN Length; + + Destination8 = Buffer; + Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); + Length = *ReadSize; + while (Length--) { + *(Destination8++) = *(Source8++); + } + + return EFI_SUCCESS; +} + +CHAR16 * +AsciiToUnicode ( + IN CHAR8 *Ascii, + IN UINTN *StrLen OPTIONAL + ) +/*++ + +Routine Description: + Convert the passed in Ascii string to Unicode. + Optionally return the length of the strings. + +Arguments: + Ascii - Ascii string to convert + StrLen - Length of string + +Returns: + Pointer to malloc'ed Unicode version of Ascii + +--*/ +{ + UINTN Index; + CHAR16 *Unicode; + + // + // Allocate a buffer for unicode string + // + for (Index = 0; Ascii[Index] != '\0'; Index++) + ; + Unicode = malloc ((Index + 1) * sizeof (CHAR16)); + if (Unicode == NULL) { + return NULL; + } + + for (Index = 0; Ascii[Index] != '\0'; Index++) { + Unicode[Index] = (CHAR16) Ascii[Index]; + } + + Unicode[Index] = '\0'; + + if (StrLen != NULL) { + *StrLen = Index; + } + + return Unicode; +} + +UINTN +CountSeparatorsInString ( + IN CONST CHAR16 *String, + IN CHAR16 Separator + ) +/*++ + +Routine Description: + Count the number of separators in String + +Arguments: + String - String to process + Separator - Item to count + +Returns: + Number of Separator in String + +--*/ +{ + UINTN Count; + + for (Count = 0; *String != '\0'; String++) { + if (*String == Separator) { + Count++; + } + } + + return Count; +} + +/** + Store the ModHandle in an array indexed by the Pdb File name. + The ModHandle is needed to unload the image. + @param ImageContext - Input data returned from PE Laoder Library. Used to find the + .PDB file name of the PE Image. + @param ModHandle - Returned from LoadLibraryEx() and stored for call to + FreeLibrary(). + @return return EFI_SUCCESS when ModHandle was stored. +--*/ +EFI_STATUS +AddModHandle ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN VOID *ModHandle + ) + +{ + UINTN Index; + PDB_NAME_TO_MOD_HANDLE *Array; + UINTN PreviousSize; + PDB_NAME_TO_MOD_HANDLE *TempArray; + HANDLE Handle; + UINTN Size; + + // + // Return EFI_ALREADY_STARTED if this DLL has already been loaded + // + Array = mPdbNameModHandleArray; + for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) { + if (Array->PdbPointer != NULL && Array->ModHandle == ModHandle) { + return EFI_ALREADY_STARTED; + } + } + + Array = mPdbNameModHandleArray; + for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) { + if (Array->PdbPointer == NULL) { + // + // Make a copy of the stirng and store the ModHandle + // + Handle = GetProcessHeap (); + Size = AsciiStrLen (ImageContext->PdbPointer) + 1; + Array->PdbPointer = HeapAlloc ( Handle, HEAP_ZERO_MEMORY, Size); + ASSERT (Array->PdbPointer != NULL); + + AsciiStrCpyS (Array->PdbPointer, Size, ImageContext->PdbPointer); + Array->ModHandle = ModHandle; + return EFI_SUCCESS; + } + } + + // + // No free space in mPdbNameModHandleArray so grow it by + // MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE entires. + // + PreviousSize = mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE); + mPdbNameModHandleArraySize += MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE; + // + // re-allocate a new buffer and copy the old values to the new locaiton. + // + TempArray = HeapAlloc (GetProcessHeap (), + HEAP_ZERO_MEMORY, + mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE) + ); + + CopyMem ((VOID *) (UINTN) TempArray, (VOID *) (UINTN)mPdbNameModHandleArray, PreviousSize); + + HeapFree (GetProcessHeap (), 0, mPdbNameModHandleArray); + + mPdbNameModHandleArray = TempArray; + if (mPdbNameModHandleArray == NULL) { + ASSERT (FALSE); + return EFI_OUT_OF_RESOURCES; + } + + return AddModHandle (ImageContext, ModHandle); +} + +/** + Return the ModHandle and delete the entry in the array. + @param ImageContext - Input data returned from PE Laoder Library. Used to find the + .PDB file name of the PE Image. + @return + ModHandle - ModHandle assoicated with ImageContext is returned + NULL - No ModHandle associated with ImageContext +**/ +VOID * +RemoveModHandle ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + UINTN Index; + PDB_NAME_TO_MOD_HANDLE *Array; + + if (ImageContext->PdbPointer == NULL) { + // + // If no PDB pointer there is no ModHandle so return NULL + // + return NULL; + } + + Array = mPdbNameModHandleArray; + for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) { + if ((Array->PdbPointer != NULL) && (AsciiStrCmp(Array->PdbPointer, ImageContext->PdbPointer) == 0)) { + // + // If you find a match return it and delete the entry + // + HeapFree (GetProcessHeap (), 0, Array->PdbPointer); + Array->PdbPointer = NULL; + return Array->ModHandle; + } + } + + return NULL; +} + +VOID +EFIAPI +PeCoffLoaderRelocateImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + EFI_STATUS Status; + VOID *DllEntryPoint; + CHAR16 *DllFileName; + HMODULE Library; + UINTN Index; + + ASSERT (ImageContext != NULL); + // + // If we load our own PE COFF images the Windows debugger can not source + // level debug our code. If a valid PDB pointer exists use it to load + // the *.dll file as a library using Windows* APIs. This allows + // source level debug. The image is still loaded and relocated + // in the Framework memory space like on a real system (by the code above), + // but the entry point points into the DLL loaded by the code bellow. + // + + DllEntryPoint = NULL; + + // + // Load the DLL if it's not an EBC image. + // + if ((ImageContext->PdbPointer != NULL) && + (ImageContext->Machine != EFI_IMAGE_MACHINE_EBC)) { + // + // Convert filename from ASCII to Unicode + // + DllFileName = AsciiToUnicode (ImageContext->PdbPointer, &Index); + + // + // Check that we have a valid filename + // + if (Index < 5 || DllFileName[Index - 4] != '.') { + free (DllFileName); + + // + // Never return an error if PeCoffLoaderRelocateImage() succeeded. + // The image will run, but we just can't source level debug. If we + // return an error the image will not run. + // + return; + } + // + // Replace .PDB with .DLL on the filename + // + DllFileName[Index - 3] = 'D'; + DllFileName[Index - 2] = 'L'; + DllFileName[Index - 1] = 'L'; + + // + // Load the .DLL file into the user process's address space for source + // level debug + // + Library = LoadLibraryEx (DllFileName, NULL, DONT_RESOLVE_DLL_REFERENCES); + if (Library != NULL) { + // + // InitializeDriver is the entry point we put in all our EFI DLL's. The + // DONT_RESOLVE_DLL_REFERENCES argument to LoadLIbraryEx() suppresses the + // normal DLL entry point of DllMain, and prevents other modules that are + // referenced in side the DllFileName from being loaded. There is no error + // checking as the we can point to the PE32 image loaded by Tiano. This + // step is only needed for source level debugging + // + DllEntryPoint = (VOID *) (UINTN) GetProcAddress (Library, "InitializeDriver"); + + } + + if ((Library != NULL) && (DllEntryPoint != NULL)) { + Status = AddModHandle (ImageContext, Library); + if (Status == EFI_ALREADY_STARTED) { + // + // If the DLL has already been loaded before, then this instance of the DLL can not be debugged. + // + ImageContext->PdbPointer = NULL; + SecPrint ("WARNING: DLL already loaded. No source level debug %S.\n\r", DllFileName); + } else { + // + // This DLL is not already loaded, so source level debugging is supported. + // + ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) DllEntryPoint; + SecPrint ("LoadLibraryEx (\n\r %S,\n\r NULL, DONT_RESOLVE_DLL_REFERENCES)\n\r", DllFileName); + } + } else { + SecPrint ("WARNING: No source level debug %S. \n\r", DllFileName); + } + + free (DllFileName); + } +} + +VOID +EFIAPI +PeCoffLoaderUnloadImageExtraAction ( + IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext +) +{ + VOID *ModHandle; + + ASSERT (ImageContext != NULL); + + ModHandle = RemoveModHandle (ImageContext); + if (ModHandle != NULL) { + FreeLibrary (ModHandle); + SecPrint ("FreeLibrary (\n\r %s)\n\r", ImageContext->PdbPointer); + } else { + SecPrint ("WARNING: Unload image without source level debug\n\r"); + } +} + +VOID +_ModuleEntryPoint ( + VOID + ) +{ +} diff --git a/CdeEmuPkg/Win/Host/WinHost.inf b/CdeEmuPkg/Win/Host/WinHost.inf new file mode 100644 index 00000000000..0b7206b6424 --- /dev/null +++ b/CdeEmuPkg/Win/Host/WinHost.inf @@ -0,0 +1,109 @@ +## @file +# Entry Point of Win Emulator +# +# Main executable file of Win Emulator that loads Sec core after initialization finished. +# Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = WinHost + FILE_GUID = 62E8F833-2B0A-4C19-A966-63C180588BE7 + MODULE_TYPE = USER_DEFINED + VERSION_STRING = 1.0 + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + EmulatorPkg/Win/Host/WinMemoryAllocationLib.c + EmulatorPkg/Win/Host/WinGopInput.c + EmulatorPkg/Win/Host/WinGopScreen.c + EmulatorPkg/Win/Host/WinGop.h + EmulatorPkg/Win/Host/WinFileSystem.c + EmulatorPkg/Win/Host/WinBlockIo.c + EmulatorPkg/Win/Host/WinThunk.c + EmulatorPkg/Win/Host/WinHost.h + WinHost.c + EmulatorPkg/Win/Host/WinPacketFilter.c + EmulatorPkg/Win/Host/WinInclude.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + NetworkPkg/NetworkPkg.dec + EmulatorPkg/EmulatorPkg.dec + +[LibraryClasses] + DebugLib + PcdLib + PrintLib + BaseMemoryLib + BaseLib + PeCoffLib + ThunkPpiList + ThunkProtocolList + PpiListLib + PeiServicesLib + FrameBufferBltLib + +[Ppis] + gEmuThunkPpiGuid + +[Protocols] + gEmuIoThunkProtocolGuid + gEmuGraphicsWindowProtocolGuid + gEmuBlockIoProtocolGuid + gEfiSimpleFileSystemProtocolGuid + gEmuSnpProtocolGuid + +[Guids] + gEfiFileSystemVolumeLabelInfoIdGuid # SOMETIMES_CONSUMED + gEfiFileInfoGuid # SOMETIMES_CONSUMED + gEfiFileSystemInfoGuid # SOMETIMES_CONSUMED + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack + + gEmulatorPkgTokenSpaceGuid.PcdEmuBootMode + gEmulatorPkgTokenSpaceGuid.PcdEmuFirmwareVolume + gEmulatorPkgTokenSpaceGuid.PcdEmuMemorySize + gEmulatorPkgTokenSpaceGuid.PcdEmuFdBaseAddress + gEmulatorPkgTokenSpaceGuid.PcdEmuVirtualDisk + gEmulatorPkgTokenSpaceGuid.PcdEmuGop|L"GOP Window" + gEmulatorPkgTokenSpaceGuid.PcdEmuFileSystem + gEmulatorPkgTokenSpaceGuid.PcdPeiServicesTablePage + gEmulatorPkgTokenSpaceGuid.PcdEmuNetworkInterface|L"0" + +[BuildOptions] + MSFT:*_*_*_DLINK_FLAGS == /out:"$(BIN_DIR)\$(BASE_NAME).exe" /base:0x10000000 /pdb:"$(BIN_DIR)\$(BASE_NAME).pdb" + MSFT:*_*_*_CC_FLAGS == /nologo /W4 /WX /Gy /c /D UNICODE /Od /Oy- /FIAutoGen.h /EHs-c- /GF /Gs8192 /Zi /Gm /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE + MSFT:*_*_*_PP_FLAGS == /nologo /E /TC /FIAutoGen.h + + MSFT:*_VS2015_IA32_DLINK_FLAGS = /LIBPATH:"%VS2015_PREFIX%Lib" /LIBPATH:"%VS2015_PREFIX%VC\Lib" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib vcruntimed.lib ucrtd.lib + MSFT:*_VS2015x86_IA32_DLINK_FLAGS = /LIBPATH:"%VS2015_PREFIX%Lib" /LIBPATH:"%VS2015_PREFIX%VC\Lib" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib vcruntimed.lib ucrtd.lib + MSFT:*_VS2017_IA32_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x86" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_VS2019_IA32_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x86" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_*_IA32_ASM_FLAGS == /nologo /W3 /WX /c /coff /Cx /Zd /W0 /Zi + MSFT:*_*_IA32_ASMLINK_FLAGS == /link /nologo /tiny + + MSFT:*_VS2015_X64_DLINK_FLAGS = /LIBPATH:"%VS2015_PREFIX%VC\Lib\AMD64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_VS2015x86_X64_DLINK_FLAGS = /LIBPATH:"%VS2015_PREFIX%VC\Lib\AMD64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_VS2017_X64_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_VS2019_X64_DLINK_FLAGS = /LIBPATH:"%VCToolsInstallDir%lib\x64" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:AMD64 /LTCG Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib + MSFT:*_*_X64_ASM_FLAGS == /nologo /W3 /WX /c /Cx /Zd /W0 /Zi + MSFT:*_*_X64_ASMLINK_FLAGS == /link /nologo + + GCC:*_CLANGPDB_X64_DLINK_FLAGS == /out:"$(BIN_DIR)\$(BASE_NAME).exe" /base:0x10000000 /pdb:"$(BIN_DIR)\$(BASE_NAME).pdb" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x64" /LIBPATH:"%VCToolsInstallDir%lib\x64" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /OPT:REF /DEBUG /MACHINE:AMD64 Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib /lldmap /EXPORT:InitializeDriver=_ModuleEntryPoint + GCC:*_CLANGPDB_X64_CC_FLAGS == -m64 -g -fshort-wchar -fno-strict-aliasing -Wall -c -include AutoGen.h -D _CRT_SECURE_NO_WARNINGS -Wnonportable-include-path -D UNICODE -D _CRT_SECURE_NO_DEPRECATE + + GCC:*_CLANGPDB_IA32_DLINK_FLAGS == /out:"$(BIN_DIR)\$(BASE_NAME).exe" /base:0x10000000 /pdb:"$(BIN_DIR)\$(BASE_NAME).pdb" /LIBPATH:"%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86" /LIBPATH:"%WindowsSdkDir%lib\%WindowsSDKLibVersion%\um\x86" /LIBPATH:"%VCToolsInstallDir%ib\x86" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /OPT:REF /DEBUG /MACHINE:I386 Kernel32.lib MSVCRTD.lib vcruntimed.lib ucrtd.lib Gdi32.lib User32.lib Winmm.lib Advapi32.lib /lldmap /EXPORT:InitializeDriver=_ModuleEntryPoint + GCC:*_CLANGPDB_IA32_CC_FLAGS == -m32 -g -fshort-wchar -fno-strict-aliasing -Wall -c -include AutoGen.h -D _CRT_SECURE_NO_WARNINGS -Wnonportable-include-path -D UNICODE -D _CRT_SECURE_NO_DEPRECATE diff --git a/CdeMnwPkg/FmpBlueSampleDevice.dsc b/CdeMnwPkg/FmpBlueSampleDevice.dsc new file mode 100644 index 00000000000..7b69740e0e5 --- /dev/null +++ b/CdeMnwPkg/FmpBlueSampleDevice.dsc @@ -0,0 +1,58 @@ +#/** @file +# FmpDxe driver for Blue Sample device firmware update. +# +# Copyright (c) 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +#**/ + + FmpDevicePkg/FmpDxe/FmpDxe.inf { + + # + # ESRT and FMP GUID for sample device capsule update + # + FILE_GUID = $(FMP_BLUE_SAMPLE_DEVICE) + + # + # Unicode name string that is used to populate FMP Image Descriptor for this capsule update module + # + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName|L"Sample Firmware Device" + + # + # ESRT and FMP Lowest Support Version for this capsule update module + # 000.000.000.000 + # + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceBuildTimeLowestSupportedVersion|0x00000000 + + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSeconds|2 + + # + # Capsule Update Progress Bar Color. Set to Blue (RGB) (0, 0, 255) + # + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressColor|0x000000FF + + # + # Certificates used to authenticate capsule update image + # + !include Vlv2TbltDevicePkg/FmpCertificate.dsc + + + # + # Generic libraries that are used "as is" by all FMP modules + # + FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf + FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf + # + # Platform specific capsule policy library + # + CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf + # + # Device specific library that processes a capsule and updates the FW storage device + # + FmpDeviceLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.inf + FmpDependencyLib|FmpDevicePkg\Library\FmpDependencyLib\FmpDependencyLib.inf + FmpDependencyCheckLib|FmpDevicePkg\Library\FmpDependencyCheckLibNull\FmpDependencyCheckLibNull.inf + FmpDependencyDeviceLib|FmpDevicePkg\Library\FmpDependencyDeviceLibNull\FmpDependencyDeviceLibNull.inf + } diff --git a/CdeMnwPkg/FmpGreenSampleDevice.dsc b/CdeMnwPkg/FmpGreenSampleDevice.dsc new file mode 100644 index 00000000000..408a76dfd47 --- /dev/null +++ b/CdeMnwPkg/FmpGreenSampleDevice.dsc @@ -0,0 +1,58 @@ +#/** @file +# FmpDxe driver for Green Sample device firmware update. +# +# Copyright (c) 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +#**/ + + FmpDevicePkg/FmpDxe/FmpDxe.inf { + + # + # ESRT and FMP GUID for sample device capsule update + # + FILE_GUID = $(FMP_GREEN_SAMPLE_DEVICE) + + # + # Unicode name string that is used to populate FMP Image Descriptor for this capsule update module + # + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName|L"Sample Firmware Device" + + # + # ESRT and FMP Lowest Support Version for this capsule update module + # 000.000.000.000 + # + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceBuildTimeLowestSupportedVersion|0x00000000 + + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSeconds|2 + + # + # Capsule Update Progress Bar Color. Set to Green (RGB) (0, 255, 0) + # + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressColor|0x0000FF00 + + # + # Certificates used to authenticate capsule update image + # + !include Vlv2TbltDevicePkg/FmpCertificate.dsc + + + # + # Generic libraries that are used "as is" by all FMP modules + # + FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf + FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf + # + # Platform specific capsule policy library + # + CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf + # + # Device specific library that processes a capsule and updates the FW storage device + # + FmpDeviceLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.inf + FmpDependencyLib|FmpDevicePkg\Library\FmpDependencyLib\FmpDependencyLib.inf + FmpDependencyCheckLib|FmpDevicePkg\Library\FmpDependencyCheckLibNull\FmpDependencyCheckLibNull.inf + FmpDependencyDeviceLib|FmpDevicePkg\Library\FmpDependencyDeviceLibNull\FmpDependencyDeviceLibNull.inf + } diff --git a/CdeMnwPkg/FmpMinnowMaxSystem.dsc b/CdeMnwPkg/FmpMinnowMaxSystem.dsc new file mode 100644 index 00000000000..a136a11f9e5 --- /dev/null +++ b/CdeMnwPkg/FmpMinnowMaxSystem.dsc @@ -0,0 +1,62 @@ +#/** @file +# FmpDxe driver for Minnow Max system firmware update. +# +# Copyright (c) 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +#**/ + + FmpDevicePkg/FmpDxe/FmpDxe.inf { + + # + # ESRT and FMP GUID for system firmware capsule update + # + FILE_GUID = $(FMP_MINNOW_MAX_SYSTEM) + + # + # Unicode name string that is used to populate FMP Image Descriptor for this capsule update module + # + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName|L"Minnow Max System Firmware Device" + + # + # ESRT and FMP Lowest Support Version for this capsule update module + # 000.000.000.000 + # + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceBuildTimeLowestSupportedVersion|0x00000000 + + gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpLowestSupportedVersion|0x00000000 + gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersion|0x00000000 + gPlatformModuleTokenSpaceGuid.PcdSystemFirmwareFmpVersionString|"000.000.000.000" + + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSeconds|4 + + # + # Capsule Update Progress Bar Color. Set to Purple (RGB) (255, 0, 255) + # + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressColor|0x00FF00FF + + # + # Certificates used to authenticate capsule update image + # + !include Vlv2TbltDevicePkg/FmpCertificate.dsc + + + # + # Generic libraries that are used "as is" by all FMP modules + # + FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf + FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf + # + # Platform specific capsule policy library + # + CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf + # + # Device specific library that processes a capsule and updates the FW storage device + # + FmpDeviceLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.inf + FmpDependencyLib|FmpDevicePkg\Library\FmpDependencyLib\FmpDependencyLib.inf + FmpDependencyCheckLib|FmpDevicePkg\Library\FmpDependencyCheckLibNull\FmpDependencyCheckLibNull.inf + FmpDependencyDeviceLib|FmpDevicePkg\Library\FmpDependencyDeviceLibNull\FmpDependencyDeviceLibNull.inf + } diff --git a/CdeMnwPkg/FmpRedSampleDevice.dsc b/CdeMnwPkg/FmpRedSampleDevice.dsc new file mode 100644 index 00000000000..4e785b5b792 --- /dev/null +++ b/CdeMnwPkg/FmpRedSampleDevice.dsc @@ -0,0 +1,58 @@ +#/** @file +# FmpDxe driver for Red Sample device firmware update. +# +# Copyright (c) 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +#**/ + + FmpDevicePkg/FmpDxe/FmpDxe.inf { + + # + # ESRT and FMP GUID for sample device capsule update + # + FILE_GUID = $(FMP_RED_SAMPLE_DEVICE) + + # + # Unicode name string that is used to populate FMP Image Descriptor for this capsule update module + # + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName|L"Sample Firmware Device" + + # + # ESRT and FMP Lowest Support Version for this capsule update module + # 000.000.000.000 + # + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceBuildTimeLowestSupportedVersion|0x00000000 + + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSeconds|2 + + # + # Capsule Update Progress Bar Color. Set to Blue (RGB) (255, 0, 0) + # + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressColor|0x00FF0000 + + # + # Certificates used to authenticate capsule update image + # + !include Vlv2TbltDevicePkg/FmpCertificate.dsc + + + # + # Generic libraries that are used "as is" by all FMP modules + # + FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf + FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf + # + # Platform specific capsule policy library + # + CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf + # + # Device specific library that processes a capsule and updates the FW storage device + # + FmpDeviceLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.inf + FmpDependencyLib|FmpDevicePkg\Library\FmpDependencyLib\FmpDependencyLib.inf + FmpDependencyCheckLib|FmpDevicePkg\Library\FmpDependencyCheckLibNull\FmpDependencyCheckLibNull.inf + FmpDependencyDeviceLib|FmpDevicePkg\Library\FmpDependencyDeviceLibNull\FmpDependencyDeviceLibNull.inf + } diff --git a/CdeMnwPkg/PlatformPkg.fdf b/CdeMnwPkg/PlatformPkg.fdf new file mode 100644 index 00000000000..116df66c2ed --- /dev/null +++ b/CdeMnwPkg/PlatformPkg.fdf @@ -0,0 +1,1036 @@ +#/** @file +# FDF file of Platform. +# +# Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +#**/ + +[Defines] +DEFINE FLASH_BASE = 0xFF800000 #The base address of the 8Mb FLASH Device. +DEFINE FLASH_SIZE = 0x00800000 #The flash size in bytes of the 8Mb FLASH Device. +DEFINE FLASH_BLOCK_SIZE = 0x1000 #The block size in bytes of the 8Mb FLASH Device. +DEFINE FLASH_NUM_BLOCKS = 0x800 #The number of blocks in 8Mb FLASH Device. + +DEFINE FLASH_REGION_VLVMICROCODE_OFFSET = 0x00400000 +DEFINE FLASH_REGION_VLVMICROCODE_SIZE = 0x00040000 +DEFINE FLASH_REGION_VLVMICROCODE_BASE = 0xFFC00000 + +DEFINE FLASH_REGION_NV_STORAGE_VARIABLE_OFFSET = 0x00440000 +DEFINE FLASH_REGION_NV_STORAGE_VARIABLE_SIZE = 0x0003E000 + +DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_OFFSET = 0x0047E000 +DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_SIZE = 0x00002000 + +DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_OFFSET = 0x00480000 +DEFINE FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_SIZE = 0x00040000 + +DEFINE FLASH_REGION_FVMAIN_OFFSET = 0x00510000 +DEFINE FLASH_REGION_FVMAIN_SIZE = 0x00220000 + +DEFINE FLASH_REGION_VPD_OFFSET = 0x00730000 +DEFINE FLASH_REGION_VPD_SIZE = 0x00010000 + +DEFINE FLASH_REGION_FV_RECOVERY2_OFFSET = 0x00740000 +DEFINE FLASH_REGION_FV_RECOVERY2_SIZE = 0x00050000 + +DEFINE FLASH_REGION_FV_RECOVERY_OFFSET = 0x00790000 +DEFINE FLASH_REGION_FV_RECOVERY_SIZE = 0x00070000 + +################################################################################ +# +# FD Section +# The [FD] Section is made up of the definition statements and a +# description of what goes into the Flash Device Image. Each FD section +# defines one flash "device" image. A flash device image may be one of +# the following: Removable media bootable image (like a boot floppy +# image,) an Option ROM image (that would be "flashed" into an add-in +# card,) a System "Flash" image (that would be burned into a system's +# flash) or an Update ("Capsule") image that will be used to update and +# existing system flash. +# +################################################################################ +[FD.Vlv] +BaseAddress = $(FLASH_BASE)|gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress #The base address of the 3Mb FLASH Device. +Size = $(FLASH_SIZE)|gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize #The flash size in bytes of the 3Mb FLASH Device. +ErasePolarity = 1 +BlockSize = $(FLASH_BLOCK_SIZE) #The block size in bytes of the 3Mb FLASH Device. +NumBlocks = $(FLASH_NUM_BLOCKS) #The number of blocks in 3Mb FLASH Device. + +# +#Flash location override based on actual flash map +# +SET gPlatformModuleTokenSpaceGuid.PcdFlashAreaBaseAddress = $(FLASH_BASE) +SET gPlatformModuleTokenSpaceGuid.PcdFlashAreaSize = $(FLASH_SIZE) + +SET gPlatformModuleTokenSpaceGuid.PcdBiosRomBase = $(FLASH_BASE) +SET gPlatformModuleTokenSpaceGuid.PcdBiosRomSize = $(FLASH_SIZE) + +SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchAddress = $(FLASH_REGION_VLVMICROCODE_BASE) + 0x60 +SET gUefiCpuPkgTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize = $(FLASH_REGION_VLVMICROCODE_SIZE) - 0x60 + +################################################################################ +# +# Following are lists of FD Region layout which correspond to the locations of different +# images within the flash device. +# +# Regions must be defined in ascending order and may not overlap. +# +# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by +# the pipe "|" character, followed by the size of the region, also in hex with the leading +# "0x" characters. Like: +# Offset|Size +# PcdOffsetCName|PcdSizeCName +# RegionType +# Fv Size can be adjusted; FVMAIN_COMPACT can be reduced to 0x120000, and FV_RECOVERY can be enlarged to 0x80000 +# +################################################################################ + + # + # IFWI Header + # +0x0000|0x1000 +FILE=Vlv2TbltDevicePkg/Stitch/IFWIHeader/IFWI_HEADER.bin + + # + # CPU Microcodes + # + +$(FLASH_REGION_VLVMICROCODE_OFFSET)|$(FLASH_REGION_VLVMICROCODE_SIZE) +gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeAddress|gPlatformModuleTokenSpaceGuid.PcdFlashMicroCodeSize +FV = MICROCODE_FV +$(FLASH_REGION_NV_STORAGE_VARIABLE_OFFSET)|$(FLASH_REGION_NV_STORAGE_VARIABLE_SIZE) +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize +#NV_VARIABLE_STORE +DATA = { + ## This is the EFI_FIRMWARE_VOLUME_HEADER + # ZeroVector [] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + # FileSystemGuid: gEfiSystemNvDataFvGuid = + # { 0xFFF12B8D, 0x7696, 0x4C8B, { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }} + 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C, + 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50, + # FvLength: 0x80000 + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + #Signature "_FVH" #Attributes + 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00, + #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision + 0x48, 0x00, 0x2A, 0x09, 0x00, 0x00, 0x00, 0x02, + #Blockmap[0]: 7 Blocks * 0x10000 Bytes / Block + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + #Blockmap[1]: End + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ## This is the VARIABLE_STORE_HEADER +!if $(SECURE_BOOT_ENABLE) == TRUE + #Signature: gEfiAuthenticatedVariableGuid = + # { 0xaaf32c78, 0x947b, 0x439a, { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }} + 0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43, + 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92, +!else + #Signature: gEfiVariableGuid = + # { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }} + 0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41, + 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d, +!endif + #Size: 0x3E000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x03DFB8 + # This can speed up the Variable Dispatch a bit. + 0xB8, 0xDF, 0x03, 0x00, + #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32 + 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +} + + +$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_OFFSET)|$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_WORKING_SIZE) +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize +#NV_FTW_WORKING +DATA = { + # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid = + # { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95 }} + 0x2B, 0x29, 0x58, 0x9E, 0x68, 0x7C, 0x7D, 0x49, + 0xA0, 0xCE, 0x65, 0x0, 0xFD, 0x9F, 0x1B, 0x95, + + # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved + 0xE2, 0x33, 0xF2, 0x3, 0xFE, 0xFF, 0xFF, 0xFF, + # WriteQueueSize: UINT64 #Size: 0x2000 - 0x20 (FTW_WORKING_HEADER) = 0x1FE0 + 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +} + +$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_OFFSET)|$(FLASH_REGION_NVSTORAGE_SUBREGION_NV_FTW_SPARE_SIZE) +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + + # + # Main Block + # +$(FLASH_REGION_FVMAIN_OFFSET)|$(FLASH_REGION_FVMAIN_SIZE) +gPlatformModuleTokenSpaceGuid.PcdFlashFvMainBase|gPlatformModuleTokenSpaceGuid.PcdFlashFvMainSize +FV = FVMAIN_COMPACT + +$(FLASH_REGION_VPD_OFFSET)|$(FLASH_REGION_VPD_SIZE) +gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress +FILE = $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/8C3D856A-9BE6-468E-850A-24F7A8D38E08.bin + + # + # FV Recovery#2 + # +$(FLASH_REGION_FV_RECOVERY2_OFFSET)|$(FLASH_REGION_FV_RECOVERY2_SIZE) +gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Base|gPlatformModuleTokenSpaceGuid.PcdFlashFvRecovery2Size +FV = FVRECOVERY2 + + # + # FV Recovery + # +$(FLASH_REGION_FV_RECOVERY_OFFSET)|$(FLASH_REGION_FV_RECOVERY_SIZE) +gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoveryBase|gPlatformModuleTokenSpaceGuid.PcdFlashFvRecoverySize +FV = FVRECOVERY + +################################################################################ +# +# FV Section +# +# [FV] section is used to define what components or modules are placed within a flash +# device file. This section also defines order the components and modules are positioned +# within the image. The [FV] section consists of define statements, set statements and +# module statements. +# +################################################################################ +[FV.MICROCODE_FV] +BlockSize = $(FLASH_BLOCK_SIZE) +FvAlignment = 16 +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = FALSE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE + +FILE RAW = 197DB236-F856-4924-90F8-CDF12FB875F3 { + $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/$(DXE_ARCHITECTURE)/MicrocodeUpdates.bin +} + +!if $(RECOVERY_ENABLE) +[FV.FVRECOVERY_COMPONENTS] +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 + +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchUsb.inf +INF MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf +INF MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf +INF MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf +INF FatPkg/FatPei/FatPei.inf +INF MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf +INF SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoadPei.inf +!endif + +################################################################################ +# +# FV Section +# +# [FV] section is used to define what components or modules are placed within a flash +# device file. This section also defines order the components and modules are positioned +# within the image. The [FV] section consists of define statements, set statements and +# module statements. +# +################################################################################ +[FV.FVRECOVERY2] +BlockSize = $(FLASH_BLOCK_SIZE) +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 +FvNameGuid = B73FE497-B92E-416e-8326-45AD0D270092 + + + +INF Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf + +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSmbusArpDisabled.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/VlvInitPeim.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchInitPeim.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSpiPeim.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmAccess.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmControl.inf +INF UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf +INF UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf + +!if $(TPM_ENABLED) == TRUE +INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf +INF SecurityPkg/Tcg/TcgPei/TcgPei.inf +INF SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf +!endif +INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf + +!if $(ACPI50_ENABLE) == TRUE + INF MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf +!endif +!if $(PERFORMANCE_ENABLE) == TRUE +INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf +!endif + +!if $(RECOVERY_ENABLE) +FILE FV_IMAGE = 1E9D7604-EF45-46a0-BD8A-71AC78C17AC1 { + SECTION PEI_DEPEX_EXP = {gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid} + SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF { # LZMA COMPRESS GUID + SECTION FV_IMAGE = FVRECOVERY_COMPONENTS + } +} +!endif + +[FV.FVRECOVERY] +BlockSize = $(FLASH_BLOCK_SIZE) +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 +FvNameGuid = B73FE497-B92E-416e-8326-45AD0D270091 + +#KGDebug +INF CdePkg/CdeServices/CdeServicesPei.inf +INF CdePkg/CdeWelcome/buildPEI.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 RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SecCore.inf +INF MdeModulePkg/Core/Pei/PeiMain.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/CpuPeim.inf +INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf +INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf + +INF Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf + +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SeCUma.inf + +!if $(SOURCE_DEBUG_ENABLE) == TRUE + INF SourceLevelDebugPkg/DebugAgentPei/DebugAgentPei.inf +!endif + + +!if $(CAPSULE_ENABLE) == TRUE +INF MdeModulePkg/Universal/CapsulePei/CapsulePei.inf +!if $(DXE_ARCHITECTURE) == "X64" +INF MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf +!endif +!endif + +!if $(PCIESC_ENABLE) == TRUE +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchEarlyInitPeim.inf +!endif +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/MemoryInit.inf + +INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf + +[FV.FVMAIN] +BlockSize = $(FLASH_BLOCK_SIZE) +FvAlignment = 16 +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE +FvNameGuid = A881D567-6CB0-4eee-8435-2E72D33E45B5 + +APRIORI DXE { + INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf + INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf + INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf + } + +# +# gBiosIdGuid +# +FILE FREEFORM = C3E36D09-8294-4b97-A857-D5288FE33E28 { + SECTION RAW = $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/BiosId.bin + } + + # + # EDK II Related Platform codes + # + +#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 +!if $(ACPI50_ENABLE) == TRUE +INF MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf +INF MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf +!endif + + +INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf +INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf +INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf +INF MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCodeRouterSmm.inf +INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf +INF UefiCpuPkg/CpuDxe/CpuDxe.inf +INF UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf +INF MdeModulePkg/Universal/Metronome/Metronome.inf +INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf +INF MdeModulePkg/Logo/LogoDxe.inf +INF RuleOverride = UI MdeModulePkg/Application/UiApp/UiApp.inf +INF MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf +INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf +INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf +INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + +INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf +INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf +INF Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf +INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiSmm.inf +!if $(SECURE_BOOT_ENABLE) +INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +!endif + +INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + +INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf +INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf +INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf +INF Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf + + +INF Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.inf + +INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf + +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/Dptf.inf + + # + # EDK II Related Silicon codes + # +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchS3SupportDxe.inf + +INF PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmControl.inf + +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmbusDxe.inf + +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchReset.inf + +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitDxe.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitSmm.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmiDispatcher.inf +!if $(PCIESC_ENABLE) == TRUE +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPcieSmm.inf +!endif + +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiRuntime.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPolicyInitDxe.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchBiosWriteProtect.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmAccess.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PciHostBridge.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/VlvInitDxe.inf +!if $(TPM_ENABLED) == TRUE +INF SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf +INF SecurityPkg/Tcg/TcgDxe/TcgDxe.inf +INF RuleOverride = DRIVER_ACPITABLE SecurityPkg/Tcg/TcgSmm/TcgSmm.inf +!endif + +# +# EDK II Related Platform codes +# +INF Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf +INF Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf +INF Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf +INF Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf +INF Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf +INF Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PlatformCpuPolicy.inf +INF Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf +!if $(GOP_DRIVER_ENABLE) == TRUE + INF Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.inf + FILE DRIVER = FF0C8745-3270-4439-B74F-3E45F8C77064 { + SECTION DXE_DEPEX_EXP = {gPlatformGOPPolicyGuid} + SECTION PE32 = Vlv2SocBinPkg/GOP/7.2.1011/RELEASE_VS2008x86/$(DXE_ARCHITECTURE)/IntelGopDriver.efi + SECTION UI = "IntelGopDriver" +} +!endif + +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PnpDxe.inf + # + # SMM + # +INF MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf +INF MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf +INF UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf + +INF UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf +INF MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf +INF UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf + +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PowerManagement2.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/DigitalThermalSensor.inf +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/GraphicDxeInitSmm.inf + + # + # ACPI + # +INF MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf +INF MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf +INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf +INF RuleOverride = ACPITABLE2 Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/PowerManagementAcpiTables.inf + +INF RuleOverride = ACPITABLE Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf + +INF Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf + +INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf + + # + # PCI + # +INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf + +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/ISPDxe.inf + + +# +# ISA +# +INF Vlv2TbltDevicePkg/PcuSio/PcuSio.inf +!if $(SOURCE_DEBUG_ENABLE) != TRUE +INF MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf +!endif + +# +# eMMC/SD Card +# +INF MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf +INF MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf +INF MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf + +# +# IDE/SCSI/AHCI +# +INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf + +INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf + +INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +!if $(SATA_ENABLE) == TRUE +INF RuleOverride = BINARY Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SataController.inf +# + +# +INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf +INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf +!if $(SCSI_ENABLE) == TRUE +INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf +INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf +!endif +# +!endif +# Console +# +INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf +INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf +INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf +INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf +INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf +INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf +INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + # + # USB + # +!if $(USB_ENABLE) == TRUE +INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf +INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf +INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf +INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf +INF MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf +INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf +INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf +!endif + + + # + # SMBIOS + # +INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf +INF Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf + +# +# FAT file system +# +INF FatPkg/EnhancedFatDxe/Fat.inf + +# +# UEFI Shell +# +INF ShellPkg/Application/Shell/Shell.inf + +# +# dp command +# +!if $(PERFORMANCE_ENABLE) == TRUE +INF ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf +!endif + +!if $(GOP_DRIVER_ENABLE) == TRUE +FILE FREEFORM = 878AC2CC-5343-46F2-B563-51F89DAF56BA { + SECTION RAW = Vlv2SocBinPkg/GOP/7.2.1011/VBT/MNW2/Vbt.bin + SECTION UI = "IntelGopVbt" +} +!endif + +# +# Network Modules +# +!include NetworkPkg/Network.fdf.inc + +!if $(NETWORK_ENABLE) == TRUE + FILE DRIVER = 22DE1691-D65D-456a-993E-A253DD1F308C { + SECTION PE32 = Vlv2SocBinPkg/UNDI/RtkUndiDxe/$(DXE_ARCHITECTURE)/RtkUndiDxe.efi + SECTION UI = "RtkUndiDxe" + } + !if $(DXE_ARCHITECTURE) == "X64" + FILE DRIVER = 7C7467E9-8BB3-4BF1-8694-6FED7D25D13E { + SECTION PE32 = Vlv2SocBinPkg/UNDI/I211PcieUndiDxe/$(DXE_ARCHITECTURE)/E7006X3.EFI + SECTION UI = "E7006X3" + } + !endif +!endif + +!if $(CAPSULE_ENABLE) +INF MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf + +# +# Minnow Max System Firmware FMP +# +INF FILE_GUID = $(FMP_MINNOW_MAX_SYSTEM) FmpDevicePkg/FmpDxe/FmpDxe.inf + +# +# Sample Device FMP +# +INF FILE_GUID = $(FMP_GREEN_SAMPLE_DEVICE) FmpDevicePkg/FmpDxe/FmpDxe.inf +INF FILE_GUID = $(FMP_BLUE_SAMPLE_DEVICE) FmpDevicePkg/FmpDxe/FmpDxe.inf +INF FILE_GUID = $(FMP_RED_SAMPLE_DEVICE) FmpDevicePkg/FmpDxe/FmpDxe.inf + +!endif + +!if $(MICOCODE_CAPSULE_ENABLE) +INF IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf +!endif + +!if $(RECOVERY_ENABLE) +FILE FREEFORM = PCD(gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid) { + SECTION RAW = BaseTools/Source/Python/Rsa2048Sha256Sign/TestSigningPublicKey.bin + SECTION UI = "Rsa2048Sha256TestSigningPublicKey" + } +!endif + +[FV.FVMAIN_COMPACT] +BlockSize = $(FLASH_BLOCK_SIZE) +FvAlignment = 16 +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE + + + +FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { +!if $(LZMA_ENABLE) == TRUE +# LZMA Compress + SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE { + SECTION FV_IMAGE = FVMAIN + } +!else +!if $(DXE_COMPRESS_ENABLE) == TRUE +# Tiano Compress + SECTION GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE { + SECTION FV_IMAGE = FVMAIN + } +!else +# No Compress + SECTION COMPRESS PI_NONE { + SECTION FV_IMAGE = FVMAIN + } +!endif +!endif + } + +!if $(RECOVERY_ENABLE) +[FV.SystemFirmwareUpdateCargo] +FvAlignment = 16 +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE + +FILE RAW = AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215 { # PcdEdkiiSystemFirmwareFileGuid + FD = Vlv +# $(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/Vlv.fd + } + +[FmpPayload.FmpPayloadSystemFirmwareRsa2048] +IMAGE_HEADER_INIT_VERSION = 0x02 +IMAGE_TYPE_ID = 4096267b-da0a-42eb-b5eb-fef31d207cb4 # PcdSystemFmpCapsuleImageTypeIdGuid +IMAGE_INDEX = 0x1 +HARDWARE_INSTANCE = 0x0 +MONOTONIC_COUNT = 0x2 +CERTIFICATE_GUID = A7717414-C616-4977-9420-844712A735BF # RSA2048SHA256 + +FV = SystemFirmwareUpdateCargo +#FILE DATA = $(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/SYSTEMFIRMWAREUPDATECARGO.Fv + +[Capsule.Vlv2Rec] +CAPSULE_GUID = 6dcbd5ed-e82d-4c44-bda1-7194199ad92a # gEfiFmpCapsuleGuid +CAPSULE_FLAGS = PersistAcrossReset,InitiateReset +CAPSULE_HEADER_SIZE = 0x20 +CAPSULE_HEADER_INIT_VERSION = 0x1 + +FMP_PAYLOAD = FmpPayloadSystemFirmwareRsa2048 +!endif + +################################################################################ +# +# Rules are use with the [FV] section's module INF type to define +# how an FFS file is created for a given INF file. The following Rule are the default +# rules for the different module type. User can add the customized rules to define the +# content of the FFS file. +# +################################################################################ +[Rule.Common.SEC] + FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED { + PE32 PE32 Align = 8 $(INF_OUTPUT)/$(MODULE_NAME).efi + RAW BIN Align = 16 |.com + } + +[Rule.Common.SEC.BINARY] + FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED { + PE32 PE32 Align = 8 |.efi + RAW BIN Align = 16 |.com + } + +[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.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.PEIM.BIOSID] + FILE PEIM = $(NAMED_GUID) { + RAW BIN BiosId.bin + 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.USER_DEFINED.APINIT] + FILE RAW = $(NAMED_GUID) Fixed Align=4K { + RAW SEC_BIN |.com + } +#cjia 2011-07-21 +[Rule.Common.USER_DEFINED.LEGACY16] + FILE FREEFORM = $(NAMED_GUID) { + UI STRING="$(MODULE_NAME)" Optional + RAW BIN |.bin + } +#cjia + +[Rule.Common.USER_DEFINED.ASM16] + FILE FREEFORM = $(NAMED_GUID) { + UI STRING="$(MODULE_NAME)" Optional + RAW BIN |.com + } + +[Rule.Common.DXE_CORE] + FILE DXE_CORE = $(NAMED_GUID) { + 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 + 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.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_DRIVER.NATIVE_BINARY] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(WORKSPACE)/Vlv2TbltDevicePkg/IntelGopDepex/IntelGopDriver.depex + PE32 PE32 |.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 + 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.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.DXE_DRIVER.DRIVER_ACPITABLE] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + RAW ACPI Optional |.acpi + RAW ASL Optional |.aml + } + +[Rule.Common.DXE_RUNTIME_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + 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.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.DXE_SMM_DRIVER] + FILE SMM = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.DXE_SMM_DRIVER.BINARY] + FILE SMM = $(NAMED_GUID) { + SMM_DEPEX SMM_DEPEX |.depex + PE32 PE32 |.efi + RAW BIN Optional |.aml + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.DXE_SMM_DRIVER.DRIVER_ACPITABLE] + FILE SMM = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + RAW ACPI Optional |.acpi + RAW ASL Optional |.aml + } + +[Rule.Common.SMM_CORE] + FILE SMM_CORE = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.SMM_CORE.BINARY] + FILE SMM_CORE = $(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] + FILE APPLICATION = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + 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.USER_DEFINED] + FILE FREEFORM = $(NAMED_GUID) { + UI STRING="$(MODULE_NAME)" Optional + RAW BIN |.bin + } + +[Rule.Common.USER_DEFINED.BINARY] + FILE FREEFORM = $(NAMED_GUID) { + UI STRING="$(MODULE_NAME)" Optional + RAW BIN |.bin + } + +[Rule.Common.USER_DEFINED.ACPITABLE] + FILE FREEFORM = $(NAMED_GUID) { + RAW ACPI Optional |.acpi + RAW ASL Optional |.aml + } + +[Rule.Common.USER_DEFINED.ACPITABLE2] + FILE FREEFORM = $(NAMED_GUID) { + RAW ASL Optional |.aml + } + +[Rule.Common.ACPITABLE] + FILE FREEFORM = $(NAMED_GUID) { + RAW ACPI Optional |.acpi + RAW ASL Optional |.aml + } + +[Rule.Common.PEIM.FMP_IMAGE_DESC] + FILE PEIM = $(NAMED_GUID) { + RAW BIN |.acpi + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } diff --git a/CdeMnwPkg/PlatformPkgX64.dsc b/CdeMnwPkg/PlatformPkgX64.dsc new file mode 100644 index 00000000000..9ed54719ad4 --- /dev/null +++ b/CdeMnwPkg/PlatformPkgX64.dsc @@ -0,0 +1,1368 @@ +#/** @file +# Platform description. +# +# Copyright (c) 2012 - 2021, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +#**/ + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + PLATFORM_NAME = Vlv2TbltDevicePkg + PLATFORM_GUID = 465B0A0B-7AC1-443b-8F67-7B8DEC145F90 + PLATFORM_VERSION = 0.1 + DSC_SPECIFICATION = 0x00010005 + OUTPUT_DIRECTORY = Build/Vlv2TbltDevicePkgX64 + SUPPORTED_ARCHITECTURES = IA32|X64 + BUILD_TARGETS = DEBUG|RELEASE + SKUID_IDENTIFIER = DEFAULT + VPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E08 + PREBUILD = python Vlv2TbltDevicePkg/PreBuild.py + POSTBUILD = python Vlv2TbltDevicePkg/Feature/Capsule/GenerateCapsule/GenCapsuleAll.py + + DEFINE RC_BINARY_RELEASE = TRUE + # + # Platform On/Off features are defined here + # + !include Vlv2TbltDevicePkg/PlatformPkgConfig.dsc + + DEFINE PLATFORMX64_ENABLE = TRUE + + DEFINE DXE_ARCHITECTURE = X64 + + FLASH_DEFINITION = PlatformPkg.fdf +!if $(LFMA_ENABLE) == TRUE + FIX_LOAD_TOP_MEMORY_ADDRESS = 0xFFFFFFFFFFFFFFFF + DEFINE TOP_MEMORY_ADDRESS = 0xFFFFFFFFFFFFFFFF +!else + FIX_LOAD_TOP_MEMORY_ADDRESS = 0x0 + DEFINE TOP_MEMORY_ADDRESS = 0x0 +!endif + + DEFINE PLATFORM_PCIEXPRESS_BASE = 0E0000000 + +################################################################################ +# +# SKU Identification section - list of all SKU IDs supported by this +# Platform. +# +################################################################################ +[SkuIds] + 0|DEFAULT # The entry: 0|DEFAULT is reserved and always required. + +[DefaultStores] + 0|STANDARD # UEFI Standard default 0|STANDARD is reserved. + 1|MANUFACTURING # UEFI Manufacturing default 1|MANUFACTURING is reserved. + +################################################################################ +# +# Library Class section - list of all Library Classes needed by this Platform. +# +################################################################################ +!include MdePkg/MdeLibs.dsc.inc +[LibraryClasses.common] + # + # 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 +!if $(SSE2_ENABLE) == TRUE + BaseMemoryLib|MdePkg/Library/BaseMemoryLibSse2/BaseMemoryLibSse2.inf +!else + BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf +!endif + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf + PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf + PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf + PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf + CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf +!if $(RC_BINARY_RELEASE) == TRUE + PchPlatformLib|Vlv2TbltDevicePkg/Library/PchPlatformLib/PchPlatformLib.inf +!endif + # + # 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 + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiTianoCustomDecompressLib.inf + PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf + UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf + BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf + SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf + FlashDeviceLib|Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLib.inf + UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf + # + # Framework + # +!if $(S3_ENABLE) == TRUE + S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf +!else + S3BootScriptLib|MdePkg/Library/BaseS3BootScriptLibNull/BaseS3BootScriptLibNull.inf +!endif + S3IoLib|MdePkg/Library/BaseS3IoLib/BaseS3IoLib.inf + S3PciLib|MdePkg/Library/BaseS3PciLib/BaseS3PciLib.inf + + # + # Generic Modules + # +!if $(USB_ENABLE) == TRUE + UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf +!endif +!if $(SCSI_ENABLE) == TRUE + UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf +!endif + + OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf +!if $(CAPSULE_ENABLE) == TRUE + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeCapsuleLib.inf +!else + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf +!endif + FmpAuthenticationLib|MdeModulePkg/Library/FmpAuthenticationLibNull/FmpAuthenticationLibNull.inf + IniParsingLib|SignedCapsulePkg/Library/IniParsingLib/IniParsingLib.inf + PlatformFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf + MicrocodeFlashAccessLib|Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf + DisplayUpdateProgressLib|MdeModulePkg/Library/DisplayUpdateProgressLibGraphics/DisplayUpdateProgressLibGraphics.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf + IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + + # + # CPU + # + MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf + LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf + CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf + MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf + VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf + MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf + + # + # ICH + # + SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf + SmmLib|Vlv2TbltDevicePkg/Library/PchSmmLib/PchSmmLib.inf + + # + # Platform + # + TimerLib|Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf + ResetSystemLib|Vlv2TbltDevicePkg/Library/ResetSystemLib/ResetSystemLib.inf + + PlatformCmosLib|Vlv2TbltDevicePkg/Library/PlatformCmosLib/PlatformCmosLib.inf + + # + # Misc + # + MonoStatusCodeLib|Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf +!if $(TARGET) == RELEASE + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf +!else + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf + SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf +!endif + + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf +!if $(TPM_ENABLED) == TRUE + TpmCommLib|SecurityPkg/Library/TpmCommLib/TpmCommLib.inf + Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf + Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf +!endif + + PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf + +!if $(SOURCE_DEBUG_ENABLE) == TRUE + PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf + DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf + SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf +!else + PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf +!endif + + # + # CryptLib + # +!if $(TPM_ENABLED) == TRUE + TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf +!else + TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf +!endif + + BiosIdLib|BoardModulePkg/Library/BiosIdLib/DxeBiosIdLib.inf + + StallSmmLib|Vlv2TbltDevicePkg/Library/StallSmmLib/StallSmmLib.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 + + FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf + + VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf + RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf + OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf +!if $(NETWORK_TLS_ENABLE) == TRUE + TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf +!endif + Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf + Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf + Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf + + BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf + +!if $(RECOVERY_ENABLE) + EdkiiSystemCapsuleLib|SignedCapsulePkg/Library/EdkiiSystemCapsuleLib/EdkiiSystemCapsuleLib.inf +!endif + +[LibraryClasses.IA32.SEC] +!if $(PERFORMANCE_ENABLE) == TRUE + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf +!endif + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + +[LibraryClasses.IA32.PEIM, LibraryClasses.IA32.PEI_CORE, LibraryClasses.IA32.SEC] + # + # PEI phase common + # + + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf + ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf + MultiPlatformLib|Vlv2TbltDevicePkg/Library/MultiPlatformLib/MultiPlatformLib.inf + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf + CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf + MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf + +!if $(PERFORMANCE_ENABLE) == TRUE + PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf + TimerLib|Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf +!endif + +!if $(TARGET) == RELEASE + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf +!else + DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf + SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf +!endif + + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf + HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf +!if $(SOURCE_DEBUG_ENABLE) == TRUE + DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf +!endif + +[LibraryClasses.X64] + # + # DXE phase common + # + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf + + Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf +!if $(TPM_ENABLED) == TRUE + TcgPhysicalPresenceLib|SecurityPkg/Library/DxeTcgPhysicalPresenceLib/DxeTcgPhysicalPresenceLib.inf +!endif + + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf + EfiRegTableLib|Vlv2TbltDevicePkg/Library/EfiRegTableLib/EfiRegTableLib.inf + HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf + MmUnblockMemoryLib|MdePkg/Library/MmUnblockMemoryLib/MmUnblockMemoryLibNull.inf + +[LibraryClasses.X64.DXE_DRIVER] + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf +!if $(PERFORMANCE_ENABLE) == TRUE + PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + TimerLib|Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf +!endif + +!if $(SOURCE_DEBUG_ENABLE) == TRUE + DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf +!endif + + FlashDeviceLib|Vlv2TbltDevicePkg/Library/FlashDeviceLib/FlashDeviceLibDxe.inf + +[LibraryClasses.X64.DXE_CORE] + HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf + MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf +!if $(PERFORMANCE_ENABLE) == TRUE + PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf + TimerLib|Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf +!endif + +!if $(SOURCE_DEBUG_ENABLE) == TRUE + DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf +!endif + +[LibraryClasses.X64.DXE_SMM_DRIVER] + MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf + SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf + MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf + LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf + SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf + SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf + + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf + !if $(TARGET) != RELEASE + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf + !endif + +!if $(SOURCE_DEBUG_ENABLE) == TRUE + DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf + TimerLib|Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf +!endif + CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf + +!if $(TPM_ENABLED) == TRUE + TcgPpVendorLib|SecurityPkg/Library/TcgPpVendorLibNull/TcgPpVendorLibNull.inf +!endif + +[LibraryClasses.X64.SMM_CORE] + MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf + SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf + SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf + SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf + +!if $(TPM_ENABLED) == TRUE + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf +!endif + + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + +!if $(TARGET) != RELEASE + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!endif + +[LibraryClasses.X64.DXE_RUNTIME_DRIVER] + ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf +!if $(SECURE_BOOT_ENABLE) == TRUE || $(TPM_ENABLED) == TRUE + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf +!endif + +!if $(SOURCE_DEBUG_ENABLE) == TRUE + DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf +!endif + +!if $(CAPSULE_ENABLE) == TRUE + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibFmp/DxeRuntimeCapsuleLib.inf +!endif + +[LibraryClasses.common.UEFI_DRIVER] + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + +!if $(SOURCE_DEBUG_ENABLE) == TRUE + DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf +!endif + +[LibraryClasses.X64.UEFI_APPLICATION] + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + +!if $(SOURCE_DEBUG_ENABLE) == TRUE + DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf +!endif + +################################################################################ +# +# Pcd Section - list of all EDK II PCD Entries defined by this Platform +# +################################################################################ +[PcdsFeatureFlag.common] +!if $(MINI_BIOS_ENABLE) == FALSE + gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|TRUE +!else + gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom|FALSE +!endif +# +# If PcdDxeIplSwitchToLongMode is TRUE, DxeIpl will load a 64-bit DxeCore and switch to long mode to hand over to DxeCore. +# + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|TRUE + + gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserGrayOutTextStatement|TRUE + +!if $(CAPSULE_RESET_ENABLE) == TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|TRUE +!else + gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALSE +!endif + gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst|FALSE +!if $(ISA_SERIAL_STATUS_CODE_ENABLE) == TRUE + gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|TRUE +!else + gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseIsaSerial|FALSE +!endif +!if $(USB_SERIAL_STATUS_CODE_ENABLE) == TRUE + gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|TRUE +!else + gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseUsbSerial|FALSE +!endif +!if $(RAM_SERIAL_STATUS_CODE_ENABLE) == TRUE + gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|TRUE +!else + gEfiSerialPortTokenSpaceGuid.PcdStatusCodeUseRam|FALSE +!endif + + +!if $(VARIABLE_INFO_ENABLE) == TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|TRUE +!else + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|FALSE +!endif + +!if $(SOURCE_DEBUG_ENABLE) + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug|TRUE +!endif + + gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmBlockStartupThisAp|TRUE + +[PcdsFixedAtBuild.common] +!if $(SECURE_BOOT_ENABLE) == TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x22000 +!else + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x4000 +!endif + gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00000800 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x400 + gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdAriSupport|FALSE +!if $(S4_ENABLE) == TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|TRUE +!else + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE +!endif +!if $(TARGET) == RELEASE + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE +!else + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE +!endif + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE +!if $(TARGET) == RELEASE + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0 + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3 +!else + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 +!endif +!if $(PERFORMANCE_ENABLE) == TRUE + gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|0x1 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|60 +!endif + + gEfiMdeModulePkgTokenSpaceGuid.PcdLoadModuleAtFixAddressEnable|$(TOP_MEMORY_ADDRESS) + gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor|0x0 + gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor|0x01 + +!if $(SOURCE_DEBUG_ENABLE) == TRUE + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17 + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl|FALSE + gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|2 +!endif + + # + # Set SMM stack size to 16 KB. + # + gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000 + + gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } + + # + # Clear unused single certificate PCD + # + gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer|{0} + + # + # Lock all updatable firmware devices at End of DXE + # + gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiEndOfDxeEventGroupGuid)} +# gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{GUID(gEfiEventReadyToBootGuid)} + + # + # Set PcdFmpDeviceTestKeySha256Digest to {0} to disable test key detection + # +# gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest|{0} + +[PcdsFixedAtBuild.IA32] +!if $(TARGET) == RELEASE + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x0 + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x3 +!else + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 +!endif + +!if $(RECOVERY_ENABLE) + gEfiMdeModulePkgTokenSpaceGuid.PcdRecoveryFileName|L"VLV2REC.Cap" +!endif + +[PcdsPatchableInModule.common] + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6 + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x$(PLATFORM_PCIEXPRESS_BASE) + + ####################################################################################################### + # + # Begin of MRC parameters + # + + ## Memory Parameter Patchable. + # FALSE - MRC Parameters are fixed for MinnowBoard Max
+ # TRUE - MRC Parameters are patchable by following PCDs
+ # @Prompt Memory Parameter Patchable. + # @ValidList 0x80000001 | 0, 1 + gVlvRefCodePkgTokenSpaceGuid.PcdMemoryParameterPatchable|FALSE + + ## Memory Down or DIMM slot. + # 0 - DIMM
+ # 1 - Memory Down
+ # @Prompt Enable Memory Down + # @ValidList 0x80000001 | 0, 1 + gVlvRefCodePkgTokenSpaceGuid.PcdEnableMemoryDown|1 + + ## The speed of DRAM. + # 0 - 800 MHz
+ # 1 - 1066 MHz
+ # 2 - 1333 MHz
+ # 3 - 1600 MHz
+ # @Prompt DRAM Speed + # @ValidList 0x80000001 | 0, 1, 2, 3 + gVlvRefCodePkgTokenSpaceGuid.PcdDramSpeed|1 + + ## DRAM Type. + # 0 - DDR3
+ # 1 - DDR3L
+ # 2 - DDR3U
+ # 3 - DDR3All
+ # 4 - LPDDR2
+ # 5 - LPDDR3
+ # 6 - DDR4
+ # @Prompt DRAM Type + # @ValidList 0x80000001 | 0, 1, 2, 3, 4, 5, 6 + gVlvRefCodePkgTokenSpaceGuid.PcdDramType|1 + + ## Please populate DIMM slot 0 if only one DIMM is supported. + # 0 - Disable
+ # 1 - Enable
+ # @Prompt DIMM 0 Enable + # @ValidList 0x80000001 | 0, 1 + gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm0|1 + + ## DIMM 1 has to be identical to DIMM 0. + # 0 - Disable
+ # 1 - Enable
+ # @Prompt DIMM 1 Enable Type + # @ValidList 0x80000001 | 0, 1 + gVlvRefCodePkgTokenSpaceGuid.PcdEnableDimm1|0 + + ## DRAM device data width. + # 0 - x8
+ # 1 - x16
+ # 2 - x32
+ # @Prompt DIMM_DWIDTH + # @ValidList 0x80000001 | 0, 1, 2 + gVlvRefCodePkgTokenSpaceGuid.PcdDimmDataWidth|1 + + ## DRAM device data density. + # 0 - 1 Gbit
+ # 1 - 2 Gbit
+ # 2 - 4 Gbit
+ # 3 - 8 Gbit
+ # @Prompt DIMM_Density + # @ValidList 0x80000001 | 0, 1, 2, 3 + gVlvRefCodePkgTokenSpaceGuid.PcdDimmDensity|2 + + ## DRAM device data bus width. + # 0 - 8 bits
+ # 1 - 16 bits
+ # 2 - 32 bits
+ # 3 - 64 bits
+ # @Prompt DIMM_BusWidth + # @ValidList 0x80000001 | 0, 1, 2, 3 + gVlvRefCodePkgTokenSpaceGuid.PcdDimmBusWidth|3 + + ## Ranks Per DIMM or Sides Per DIMM. + # 0 - 1 Rank
+ # 1 - 2 Ranks
+ # @Prompt DIMM_Sides + # @ValidList 0x80000001 | 0, 1 + gVlvRefCodePkgTokenSpaceGuid.PcdRankPerDimm|0 + + ## tCL.

+ # @Prompt tCL + gVlvRefCodePkgTokenSpaceGuid.PcdTcl|11 + + ## tRP and tRCD in DRAM clk - 5:12.5ns, 6:15ns, etc. + # @Prompt tRP_tRCD + gVlvRefCodePkgTokenSpaceGuid.PcdTrpTrcd|11 + + ## tWR in DRAM clk. + # @Prompt tWR + gVlvRefCodePkgTokenSpaceGuid.PcdTwr|12 + + ## tWTR in DRAM clk. + # @Prompt tWTR + gVlvRefCodePkgTokenSpaceGuid.PcdTwtr|6 + + ## tRRD in DRAM clk. + # @Prompt tRRD + gVlvRefCodePkgTokenSpaceGuid.PcdTrrd|6 + + ## tRTP in DRAM clk. + # @Prompt tRTP + gVlvRefCodePkgTokenSpaceGuid.PcdTrtp|6 + + ## tFAW in DRAM clk. + # @Prompt tFAW + gVlvRefCodePkgTokenSpaceGuid.PcdTfaw|32 + + # + # End of MRC parameters. + # + ############################################################################################### + +[PcdsDynamicHii.common.DEFAULT] + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|5 # Variable: L"Timeout" + gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|L"HwErrRecSupport"|gEfiGlobalVariableGuid|0x0|1 # Variable: L"HwErrRecSupport" + gPlatformModuleTokenSpaceGuid.PcdBootState|L"BootState"|gPlatformModuleTokenSpaceGuid|0x0|TRUE + +[PcdsDynamicDefault.common.DEFAULT] + gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0x0 + !if $(TPM_ENABLED) == TRUE + gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x7b, 0x3a, 0xcd, 0x72, 0xA5, 0xFE, 0x5e, 0x4f, 0x91, 0x65, 0x4d, 0xd1, 0x21, 0x87, 0xbb, 0x13} + !endif + + ## This PCD defines the video horizontal resolution. + # This PCD could be set to 0 then video resolution could be at highest resolution. + #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800 + ## This PCD defines the video vertical resolution. + # This PCD could be set to 0 then video resolution could be at highest resolution. + #gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600 + + ## This PCD defines the Console output column and the default value is 25 according to UEFI spec. + # This PCD could be set to 0 then console output could be at max column and max row. + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|31 + ## This PCD defines the Console output row and the default value is 80 according to UEFI spec. + # This PCD could be set to 0 then console output could be at max column and max row. + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|100 + + ## The PCD is used to specify the video horizontal resolution of text setup. + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|800 + ## The PCD is used to specify the video vertical resolution of text setup. + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|600 + ## The PCD is used to specify the console output column of text setup. + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn|100 + ## The PCD is used to specify the console output column of text setup. + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow|31 + +!if $(TPM_ENABLED) == TRUE + gEfiSecurityPkgTokenSpaceGuid.PcdTpmInitializationPolicy|1 + gEfiSecurityPkgTokenSpaceGuid.PcdTpmScrtmPolicy|1 +!endif + +[PcdsDynamicExDefault.common.DEFAULT] + gEfiVLVTokenSpaceGuid.PcdTCSmbaIoBaseAddress|0x1040 + gEfiVLVTokenSpaceGuid.PcdEmmcManufacturerId|0 + gEfiVLVTokenSpaceGuid.PcdProductSerialNumber|0 + gEfiVLVTokenSpaceGuid.PcdMeasuredBootEnable|TRUE + gEfiVLVTokenSpaceGuid.PcdFTPMErrorOccur|FALSE + gEfiVLVTokenSpaceGuid.PcdFTPMErrorSkip|FALSE + gEfiVLVTokenSpaceGuid.PcdFTPMCommand|0 + gEfiVLVTokenSpaceGuid.PcdFTPMResponse|0 + gEfiVLVTokenSpaceGuid.PcdFTPMNotRespond|FALSE + gEfiVLVTokenSpaceGuid.PcdFTPMStatus|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateSmmDataPtr|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdS3BootScriptTablePrivateDataPtr|0 + gEfiVLVTokenSpaceGuid.PcdCpuLockBoxDataAddress|0 + gEfiVLVTokenSpaceGuid.PcdCpuSmramCpuDataAddress|0 + gEfiVLVTokenSpaceGuid.PcdCpuLockBoxSize|0 + gEfiSecurityPkgTokenSpaceGuid.PcdUserPhysicalPresence|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid|{GUID("$(FMP_MINNOW_MAX_SYSTEM)")}|VOID*|0x10 +!if $(RECOVERY_ENABLE) + gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareImageDescriptor|{0x0}|VOID*|0x100 + gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid|{GUID("AF9C9EB2-12AD-4D3E-A4D4-96F6C9966215")}|VOID*|0x10 +!endif + +[PcdsDynamicExVpd.common.DEFAULT] + gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer|* + +[PcdsDynamicExHii.common.DEFAULT.STANDARD] + !include Vlv2TbltDevicePkg/PlatformSetupDefaults.dsc + +[Components.IA32] +#KGDebug start + CdePkg/CdeServices/CdeServicesPei.inf + CdePkg/CdeWelcome/buildPEI.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 + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SecCore.inf + + MdeModulePkg/Core/Pei/PeiMain.inf { +!if $(TARGET) == DEBUG + + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E +!endif + + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046 + } + + Vlv2TbltDevicePkg/MonoStatusCode/MonoStatusCode.inf { +!if $(TARGET) == DEBUG + + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E +!endif + } + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/MemoryInit.inf { + + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046 + } + +!if $(RC_BINARY_RELEASE) == TRUE + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/SeCUma.inf +!endif + +!if $(RC_BINARY_RELEASE) == TRUE + Vlv2TbltDevicePkg/PlatformPei/PlatformPei.inf { + !if $(TARGET) == DEBUG + + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2E + !endif + } +!endif + +!if $(SOURCE_DEBUG_ENABLE) == TRUE + SourceLevelDebugPkg/DebugAgentPei/DebugAgentPei.inf{ + + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf + PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf + SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf + } +!endif + +!if $(TPM_ENABLED) == TRUE + SecurityPkg/Tcg/PhysicalPresencePei/PhysicalPresencePei.inf + SecurityPkg/Tcg/TcgPei/TcgPei.inf { + + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + } +!endif + + Vlv2TbltDevicePkg/PlatformInitPei/PlatformInitPei.inf { + + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6 + +!if $(TARGET) != RELEASE + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!endif + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + } + Vlv2TbltDevicePkg/FvInfoPei/FvInfoPei.inf + + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/VlvInitPeim.inf +!if $(PCIESC_ENABLE) == TRUE + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchEarlyInitPeim.inf { + + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046 + } +!endif + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchInitPeim.inf + + + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSmbusArpDisabled.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchSpiPeim.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmAccess.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PeiSmmControl.inf + MdeModulePkg/Universal/PCD/Pei/Pcd.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/CpuPeim.inf + UefiCpuPkg/CpuIoPei/CpuIoPei.inf + UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf + UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf + +!if $(RECOVERY_ENABLE) + # + # Recovery + # + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/IA32/PchUsb.inf + MdeModulePkg/Bus/Pci/EhciPei/EhciPei.inf + MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf + MdeModulePkg/Bus/Usb/UsbBotPei/UsbBotPei.inf + FatPkg/FatPei/FatPei.inf + MdeModulePkg/Universal/Disk/CdExpressPei/CdExpressPei.inf + SignedCapsulePkg/Universal/RecoveryModuleLoadPei/RecoveryModuleLoadPei.inf { + + FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibRsa2048Sha256/FmpAuthenticationLibRsa2048Sha256.inf + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + } +!endif + +!if $(CAPSULE_ENABLE) == TRUE + MdeModulePkg/Universal/CapsulePei/CapsulePei.inf +!endif + MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf { + +!if $(LZMA_ENABLE) == TRUE + NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf +!endif + } + + MdeModulePkg/Universal/Variable/Pei/VariablePei.inf + MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf + +!if $(TPM_ENABLED) == TRUE + SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf { + + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + } +!endif +!if $(ACPI50_ENABLE) == TRUE + MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf{ + + TimerLib|Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf + } + +!endif +!if $(PERFORMANCE_ENABLE) == TRUE + MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf +!endif +[Components.X64] + # + # EDK II Related Platform codes + # + #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/Core/Dxe/DxeMain.inf { + + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000046 + +!if $(DXE_CRC32_SECTION_ENABLE) == TRUE + NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf +!endif +!if $(LZMA_ENABLE) == TRUE + NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf +!endif +!if $(TARGET) != RELEASE + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!endif + } + MdeModulePkg/Universal/PCD/Dxe/Pcd.inf { + + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf + + MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf + MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf { + +!if $(TARGET) != RELEASE + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!endif + } + +!if $(CAPSULE_ENABLE) == TRUE + MdeModulePkg/Universal/CapsulePei/CapsuleX64.inf { + + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf +!if $(SOURCE_DEBUG_ENABLE) == TRUE + DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf +!endif + } +!endif + + MdeModulePkg/Universal/ReportStatusCodeRouter/Smm/ReportStatusCodeRouterSmm.inf + MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf{ + +!if $(SECURE_BOOT_ENABLE) == TRUE + NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf +!endif + +!if $(TPM_ENABLED) == TRUE + NULL|SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf +!endif + } + MdeModulePkg/Universal/Metronome/Metronome.inf + + MdeModulePkg/Universal/BdsDxe/BdsDxe.inf { + + PlatformBootManagerLib|Vlv2TbltDevicePkg/Library/DxePlatformBootManagerLib/DxePlatformBootManagerLib.inf + } + MdeModulePkg/Logo/LogoDxe.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/WatchdogTimerDxe/WatchdogTimer.inf + MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf { + + NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + NULL|MdeModulePkg/Library/VarCheckPolicyLib/VarCheckPolicyLib.inf + SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf + } + Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbSmm.inf + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiSmm.inf +!if $(SECURE_BOOT_ENABLE) == TRUE + SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf { + + PlatformSecureLib|SecurityPkg/Library/PlatformSecureLibNull/PlatformSecureLibNull.inf + + # + # Specify GUID gEfiIfrBootMaintenanceGuid, to install Secure Boot Configuration menu + # into Boot Maintenance Manager menu + # + *_*_*_VFR_FLAGS = -g b2dedc91-d59f-48d2-898a-12490c74a4e0 + } +!endif + MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf { + + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + } + + MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf + PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf + MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + + Vlv2TbltDevicePkg/FvbRuntimeDxe/FvbRuntimeDxe.inf + + Vlv2TbltDevicePkg/PlatformSetupDxe/PlatformSetupDxe.inf + + MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchS3SupportDxe.inf + PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmControl.inf + + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmbusDxe.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchReset.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitDxe.inf{ + + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043 + } + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchInitSmm.inf + + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSmiDispatcher.inf + +!if $(PCIESC_ENABLE) == TRUE + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPcieSmm.inf +!endif + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchSpiRuntime.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchPolicyInitDxe.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PchBiosWriteProtect.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SmmAccess.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PciHostBridge.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/VlvInitDxe.inf + + # + # Performance Application; Set PERFORMANCE_ENABLE=TRUE for normal boot performance and smm performance data + # +!if $(PERFORMANCE_ENABLE) == TRUE + ShellPkg/DynamicCommand/DpDynamicCommand/DpDynamicCommand.inf { + + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + } +!endif + + Vlv2TbltDevicePkg/VlvPlatformInitDxe/VlvPlatformInitDxe.inf{ + +!if $(TARGET) != RELEASE + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!endif + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + } + + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/Dptf.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PnpDxe.inf + +!if $(TPM_ENABLED) == TRUE + SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf { + + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + } + + SecurityPkg/Tcg/TcgConfigDxe/TcgConfigDxe.inf { + + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + + # + # specify GUID gEfiIfrNotInTPVPageGuid, this page will not + # be showed in TPV page. + # + *_*_*_VFR_FLAGS = -g e58809f8-fbc1-48e2-883a-a30fdc4b441e + } + + SecurityPkg/Tcg/TcgDxe/TcgDxe.inf { + + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + } + SecurityPkg/Tcg/TcgSmm/TcgSmm.inf +!endif + # + # EDK II Related Platform codes + # + Vlv2TbltDevicePkg/PlatformSmm/PlatformSmm.inf{ + + !if $(TARGET) != RELEASE + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf + !endif + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + } + Vlv2TbltDevicePkg/PlatformInfoDxe/PlatformInfoDxe.inf + Vlv2TbltDevicePkg/PlatformCpuInfoDxe/PlatformCpuInfoDxe.inf + Vlv2TbltDevicePkg/PlatformDxe/PlatformDxe.inf + + Vlv2TbltDevicePkg/PciPlatform/PciPlatform.inf + Vlv2TbltDevicePkg/SaveMemoryConfig/SaveMemoryConfig.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PlatformCpuPolicy.inf + Vlv2TbltDevicePkg/PpmPolicy/PpmPolicy.inf +!if $(GOP_DRIVER_ENABLE) == TRUE + Vlv2TbltDevicePkg/PlatformGopPolicy/PlatformGopPolicy.inf + +!endif + + + # + # SMM + # + MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf + MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf + UefiCpuPkg/CpuDxe/CpuDxe.inf + UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf + UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf + UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf + MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf + UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf + + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/PowerManagement2.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/DigitalThermalSensor.inf + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/GraphicDxeInitSmm.inf + + # + # ACPI + # + MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf { + + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xF0000043 + + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x27 + + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + } + MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf + + MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf + Vlv2DeviceRefCodePkg/ValleyView2Soc/CPU/PowerManagement/AcpiTables/PowerManagementAcpiTables.inf + + Vlv2DeviceRefCodePkg/AcpiTablesPCAT/AcpiTables.inf + + Vlv2TbltDevicePkg/AcpiPlatform/AcpiPlatform.inf + + MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf + + # + # PCI + # + MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf + + + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/ISPDxe.inf + + + # + # ISA + # + Vlv2TbltDevicePkg/PcuSio/PcuSio.inf + MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf + +!if $(ACPI50_ENABLE) == TRUE + MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf { + + TimerLib|Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf + } + MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf { + + TimerLib|Vlv2TbltDevicePkg/Library/IntelPchAcpiTimerLib/IntelPchAcpiTimerLib.inf + } +!endif + +# +# eMMC/SD Card +# + MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf + MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf + MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf + +# +# IDE/SCSI/AHCI +# + MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf + MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf + MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf + MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + FatPkg/EnhancedFatDxe/Fat.inf + 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 + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf + + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000 + } +!if $(SATA_ENABLE) == TRUE + Vlv2SocBinPkg/$(DXE_ARCHITECTURE)$(TARGET)/$(DXE_ARCHITECTURE)/SataController.inf +!endif + MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf +!if $(SCSI_ENABLE) == TRUE + MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf + MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf +!endif +# +# Console +# + MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf + MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf + MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf + MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + + # + # USB + # +!if $(USB_ENABLE) == TRUE + MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf + MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf + MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf + MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf + MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf + MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf + MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf + +!endif + + # + # SMBIOS + # + MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf + Vlv2TbltDevicePkg/SmBiosMiscDxe/SmBiosMiscDxe.inf + + # + # CPU/FW Microde + # + Vlv2SocBinPkg/Microcode/MicrocodeUpdates.inf { + + *_*_*_GENFW_FLAGS = -a 0x800 -p 0xFF + } + + + # + # Network Stacks + # +!include NetworkPkg/Network.dsc.inc + +!if $(CAPSULE_ENABLE) || $(MICOCODE_CAPSULE_ENABLE) + MdeModulePkg/Universal/EsrtFmpDxe/EsrtFmpDxe.inf + MdeModulePkg/Application/CapsuleApp/CapsuleApp.inf +!endif + +!if $(CAPSULE_ENABLE) +# !include Vlv2TbltDevicePkg/FmpMinnowMaxSystem.dsc +# !include Vlv2TbltDevicePkg/FmpGreenSampleDevice.dsc +# !include Vlv2TbltDevicePkg/FmpBlueSampleDevice.dsc +# !include Vlv2TbltDevicePkg/FmpRedSampleDevice.dsc + !include FmpMinnowMaxSystem.dsc + !include FmpGreenSampleDevice.dsc + !include FmpBlueSampleDevice.dsc + !include FmpRedSampleDevice.dsc +!endif + +!if $(MICOCODE_CAPSULE_ENABLE) + IntelSiliconPkg/Feature/Capsule/MicrocodeUpdateDxe/MicrocodeUpdateDxe.inf { + + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf + } +!endif + +[BuildOptions] +# +# Define Build Options both for EDK and EDKII drivers. +# +GCC:*_*_*_CC_FLAGS = -Wno-missing-braces + +# +# Define token for different Platform +# +!if $(SOURCE_DEBUG_ENABLE) == TRUE + MSFT:*_*_X64_GENFW_FLAGS = --keepexceptiontable + GCC:*_*_X64_GENFW_FLAGS = --keepexceptiontable + INTEL:*_*_X64_GENFW_FLAGS = --keepexceptiontable +!endif + +# +# Force PE/COFF sections to be aligned at 4KB boundaries to support page level +# protection of DXE_RUNTIME_DRIVER modules +# +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER] + MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096 + GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 + XCODE:*_*_*_DLINK_FLAGS = -segalign 0x1000 + +# +# Force PE/COFF sections to be aligned at 4KB boundaries to support page level +# protection of DXE_SMM_DRIVER/SMM_CORE modules +# +[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE] + MSFT:*_*_*_DLINK_FLAGS = /ALIGN:4096 + GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000 + XCODE:*_*_*_DLINK_FLAGS = -segalign 0x1000 + +[BuildOptions.Common.EDKII] +!if $(CLKGEN_CONFIG_EXTRA_ENABLE) == TRUE + MSFT:*_*_*_CC_FLAGS = /DCLKGEN_CONFIG_EXTRA=1 + MSFT:*_*_*_VFRPP_FLAGS = /DCLKGEN_CONFIG_EXTRA=1 + MSFT:*_*_*_APP_FLAGS = /DCLKGEN_CONFIG_EXTRA=1 + MSFT:*_*_*_PP_FLAGS = /DCLKGEN_CONFIG_EXTRA=1 + MSFT:*_*_*_ASLPP_FLAGS = /DCLKGEN_CONFIG_EXTRA=1 + GCC:*_*_*_CC_FLAGS = -DCLKGEN_CONFIG_EXTRA=1 + GCC:*_*_*_VFRPP_FLAGS = -DCLKGEN_CONFIG_EXTRA=1 + GCC:*_*_*_APP_FLAGS = -DCLKGEN_CONFIG_EXTRA=1 + GCC:*_*_*_PP_FLAGS = -DCLKGEN_CONFIG_EXTRA=1 + GCC:*_*_*_ASLPP_FLAGS = -DCLKGEN_CONFIG_EXTRA=1 +!endif + +!if $(PCIESC_ENABLE) == TRUE + MSFT:*_*_*_CC_FLAGS = /DPCIESC_SUPPORT=1 + MSFT:*_*_*_VFRPP_FLAGS = /DPCIESC_SUPPORT=1 + MSFT:*_*_*_APP_FLAGS = /DPCIESC_SUPPORT=1 + MSFT:*_*_*_PP_FLAGS = /DPCIESC_SUPPORT=1 + MSFT:*_*_*_ASLPP_FLAGS = /DPCIESC_SUPPORT=1 + GCC:*_*_*_CC_FLAGS = -DPCIESC_SUPPORT=1 + GCC:*_*_*_VFRPP_FLAGS = -DPCIESC_SUPPORT=1 + GCC:*_*_*_APP_FLAGS = -DPCIESC_SUPPORT=1 + GCC:*_*_*_PP_FLAGS = -DPCIESC_SUPPORT=1 + GCC:*_*_*_ASLPP_FLAGS = -DPCIESC_SUPPORT=1 +!endif + +!if $(SOURCE_DEBUG_ENABLE) == TRUE + !if $(TARGET) == DEBUG + MSFT:*_*_X64_CC_FLAGS = /Od /Oy- + !endif +!endif diff --git a/CdePkg b/CdePkg new file mode 160000 index 00000000000..509150ad538 --- /dev/null +++ b/CdePkg @@ -0,0 +1 @@ +Subproject commit 509150ad5387ef247357744416354ab2f5c42263 diff --git a/CdePkg.sln b/CdePkg.sln new file mode 100644 index 00000000000..08dac54b4cf --- /dev/null +++ b/CdePkg.sln @@ -0,0 +1,50 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28729.10 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CdeWelcomeDxe", "CdePkg\CdeWelcomeDxe\CdeWelcomeDxe.vcxproj", "{A9F095DD-8BE2-4576-992A-C37E1E56A46F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D50FA0CE-6F63-496A-AEFE-CC665E775B50}" + ProjectSection(SolutionItems) = preProject + CdePkg\CdeLib\CdeLib.inf = CdePkg\CdeLib\CdeLib.inf + CdePkg\CdePkg.dec = CdePkg\CdePkg.dec + CdePkg\CdePkg.dsc = CdePkg\CdePkg.dsc + CdePkg\CdeServices\CdeServicesDxe.inf = CdePkg\CdeServices\CdeServicesDxe.inf + CdePkg\CdeServices\CdeServicesPei.inf = CdePkg\CdeServices\CdeServicesPei.inf + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CdeLoadOptionsDxe", "CdePkg\CdeLoadOptionsDxe\CdeLoadOptionsDxe.vcxproj", "{6A9608DB-E447-40EA-B6D7-98CB33A5D2A3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CdeLoadOptionsPei", "CdePkg\CdeLoadOptionsPei\CdeLoadOptionsPei.vcxproj", "{6D7FB80F-0760-4095-9FE2-0F461B49B299}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CdeWelcomePei", "CdePkg\CdeWelcomePei\CdeWelcomePei.vcxproj", "{CD22E2E2-9815-452D-8BB9-781D2B826534}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A9F095DD-8BE2-4576-992A-C37E1E56A46F}.Release|x64.ActiveCfg = Release|x64 + {A9F095DD-8BE2-4576-992A-C37E1E56A46F}.Release|x64.Build.0 = Release|x64 + {A9F095DD-8BE2-4576-992A-C37E1E56A46F}.Release|x86.ActiveCfg = Release|Win32 + {A9F095DD-8BE2-4576-992A-C37E1E56A46F}.Release|x86.Build.0 = Release|Win32 + {6A9608DB-E447-40EA-B6D7-98CB33A5D2A3}.Release|x64.ActiveCfg = Release|x64 + {6A9608DB-E447-40EA-B6D7-98CB33A5D2A3}.Release|x64.Build.0 = Release|x64 + {6A9608DB-E447-40EA-B6D7-98CB33A5D2A3}.Release|x86.ActiveCfg = Release|Win32 + {6A9608DB-E447-40EA-B6D7-98CB33A5D2A3}.Release|x86.Build.0 = Release|Win32 + {6D7FB80F-0760-4095-9FE2-0F461B49B299}.Release|x64.ActiveCfg = Release|x64 + {6D7FB80F-0760-4095-9FE2-0F461B49B299}.Release|x86.ActiveCfg = Release|Win32 + {6D7FB80F-0760-4095-9FE2-0F461B49B299}.Release|x86.Build.0 = Release|Win32 + {CD22E2E2-9815-452D-8BB9-781D2B826534}.Release|x64.ActiveCfg = Release|x64 + {CD22E2E2-9815-452D-8BB9-781D2B826534}.Release|x86.ActiveCfg = Release|Win32 + {CD22E2E2-9815-452D-8BB9-781D2B826534}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AA34126F-8A18-490D-B9F4-96D6EA121627} + EndGlobalSection +EndGlobal diff --git a/CdePkgBootFlow.png b/CdePkgBootFlow.png new file mode 100644 index 00000000000..db571aa6257 Binary files /dev/null and b/CdePkgBootFlow.png differ diff --git a/README b/README deleted file mode 100644 index 60f14a654ae..00000000000 --- a/README +++ /dev/null @@ -1,72 +0,0 @@ -This repository is used by EDK II as a staging location for new -features that are not yet ready for inclusion in EDK II. - -Introduction -================= -Need place on tianocore.org where new features that are not ready for product -integration can be checked in for evaluation by the EDK II community prior to -adding to the edk2 trunk. This serves several purposes: - -* Encourage source code to be shared earlier in the development process -* Allow source code to be shared that does not yet meet all edk2 required quality criteria -* Allow source code to be shared so the EDK II community can help finish and validate new features -* Provide a location to hold new features until they are deemed ready for product integration -* Provide a location to hold new features until there is a natural point in edk2 release cycle to fully validate the new feature. -* Not intended to be used for bug fixes. -* Not intended to be used for small, simple, or low risk features. - -Process for creating, using, and maintaining staging efforts -======== -[Step 1 is already completed, it is here for documentation purposes; proceed to 2)] -1) Create a new repo called edk2-staging - a) edk2-staging is a fork of edk2 - b) edk2-staging/master tracks edk2/master - -2) edk2-staging discussions can use the existing edk2-devel mailing list for design/patch/test. - Use the following style for discussion of a specific feature branch in edk2-staging repo. - - [staging/branch]: Subject - -3) All commits to edk2-staging must follow same edk2 rules - -4) Process to add a new feature to edk2-staging - a) Maintainer sends patch email to edk2-devel mailing list announcing the creation of a new - feature branch in edk2-staging with Readme.MD. Readme.MD is in root of feature branch - with summary, owners, timeline, links to related materials. - b) Maintainer creates feature branch in edk2-staging - c) Maintainer is responsible for making sure feature is frequently synced to edk2/master - - NOTE: Feature branch may initially use a stable edk2 tag. As feature stabilizes, - syncs to edk2/master can begin. - -5) Process to update sources in feature branch - a) Commit message subject format: - - [staging/branch PATCH]: Package/Module: Subject - - b) Directly commit changes to feature branch or if community review is desired, - then use edk2-devel review process. - - NOTE: win32 binaries are not automatically generated if a feature branch includes BaseTools source changes. - -6) Process to promote an edk2-staging branch to edk2 trunk - a) Use edk2 patch review/commit process on edk2-devel mailing list. - The specific git actions used to add the feature to edk2 is at the discretion - of the maintainer(s) doing the merge. A merge commit must always contain the final - 'Reviewed-by:' tags. - b) Remove feature branch from edk2-staging and archive at https://github.com/tianocore/edk2-archive. - -7) Process to remove an edk2-staging branch - a) Stewards may periodically review of feature branches in edk2-staging (once a quarter?) - b) If no activity for extended period of time and feature is no longer deemed a candidate - for edk2 then stewards send email to edk2-devel to request deletion of feature branch. - c) If no objections from EDK II community, then feature branch is deleted and archived at - https://github.com/tianocore/edk2-archive. - -8) How to evaluate a feature in edk2-staging - a) Clone edk2 - b) Create local branch with optional platform packages - c) Build platform in local branch and verify it is stable - d) Clone edk2-staging/[branch name] - e) Create local branch with optional platform packages - f) Build platform in local branch and evaluate new feature diff --git a/README.md b/README.md new file mode 100644 index 00000000000..ffb8f20eaa9 --- /dev/null +++ b/README.md @@ -0,0 +1,325 @@ +# CdePkg - C Development Environment Package for EDK2 +* [CdePkgBlog](README.md#cdepkg-blog-at--uefi--tianocore) +* [Preface](README.md#preface) +* [Introduction](README.md#introduction) +* [Intention](README.md#intention) +* [Implementation](README.md#implementation) + * [Interface architecture](README.md#interface-architecture) + * [CdeLoadOptions/command line](README.md#cdeloadoptions--command-line) + * [Boot flow architecture](README.md#boot-flow-architecture) +* [Status](README.md#status) + * [todo](README.md#todo) +* [Howto](README.md#howto) +* [Related Projects](README.md#related-projects) +* [Revision history](README.md#revision-history) + + + +## CdePkg blog at UEFI **tianocore** +[![Repo name](https://github-readme-stats.vercel.app/api/pin/?username=KilianKegel&repo=Introduction-of-the-ACPICA-port-to-UEFI)](https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2022-01-16#introduction-of-the-acpica-port-to-uefi) +[![Repo name](https://github-readme-stats.vercel.app/api/pin/?username=KilianKegel&repo=RedFish-on-CdePkg)](https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2021-12-19#redfish-on-cdepkg) +[![Repo name](https://github-readme-stats.vercel.app/api/pin/?username=KilianKegel&repo=Using-UEFI--and-Standard-C-API-in-shell-applications-creating-MSDOS-Tools-for-UEFI)](https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2021-11-28#using-uefi--and-standard-c-api-in-shell-applications-creating-msdos-tools-for-uefi) +[![Repo name](https://github-readme-stats.vercel.app/api/pin/?username=KilianKegel&repo=my-legacy-toolbox)](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2021-11-14/README.md#my-legacy-toolbox) + +## Preface +The programming language C is standardized by the American National Standards Institute (ANSI) and the +International Organization for Standardization (ISO) first in 1989 and 1990. +The latest publicly available version of the standard from 1999 is to be found here: [C99](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf). +The original [ANSI C](https://1drv.ms/b/s!AmMwYrfjYfPyhmLlWx7oT5rO6UDg?e=ijKu1J), also known as C89 or +C90 is not officially available anymore for free. + +Both, the *language* (operators, expressions, declarations, specifiers, e.g. `if`, `while`, +`+`, `&&`, `unsigned`, `char`, `struct` ...) and the *library* (functions, parameters, structures, macros, +e.g. `NDEBUG`, `CLOCKS_PER_SEC`, `raise()`, `scanf()`, `struct lconv`, `struct tm`, `errno` ...) are specified in this document (chapters 6 and 7) +and are mandatory for an implementation that claims to meet the standard. + +In a particular C compiler / C library implementation both are completely coordinated to +each other. + +The Microsoft C/C++ compiler and its library LIBCMT.lib is an implementation of this standard; +it is primarily designed to create C/C++ programs and drivers for the Windows Operating System; +it is surely the most frequently used C compiler of them all and continuously enhanced, updated and +maintained by Microsoft. + +This compiler is not a stand alone executable that simply translates C/C++ sourcecode to object +modules. It is closely entwined with different build environments (WDK/DDK, SDK) consisting of libraries, +headerfiles, the operating system interface and platforms (x86-64/32, ARM64/32) to meet required code safety, code optimization +(size vs. speed in different shades) and maintainability (e.g. for debug and trace purpose). + +The code generation and optimization aspects are not completely documented by Microsoft +but the Microsoft compiler tends to produce machine code, that relies on the presence of +C library specified functions for storage space initialization, comparison and duplication +(`memset()`,`strcpy()`, `strcmp()`). Additionally some still undocumented function calls +are produced by the x86-32 code generator, when dealing with 64 bit integer types (`long long`), +that came into the C language standard in 1999. + +## Introduction +**CdePkg**, C Development Environment Package, introduces the use of ***Hosted Environment***, +as specified by ANSI C, for both UEFI POST and SHELL drivers. +This is a reference implementation only, using the Microsoft C compiler, linker, library +manager and IDE that comes with Visual Studio 2019 for x86 platforms. + +A *Hosted Environment* for command line applications is standard, its introduction for drivers is a **novum**. This also applies for the UEFI environment. But the wealth of computing power of current UEFI machines offers the chance to translate ANSI C +compatible sourcecode to run as UEFI POST driver. + +With the growing complexity of firmware due to the requirements for both security and trust and the +need for speed in development, use of platform-independent sourcecode allows: +* reuse of validated C sourcecode (from different origins, e.g. the open source community)[1](https://github.com/KilianKegel/CdePkg/blob/master/footnotes/footnote-1.md) +* crossdevelopment of complex firmware code on non-UEFI platforms with superb build and debug capabilities +* use of static code analysis tools[2](https://github.com/KilianKegel/CdePkg/blob/master/footnotes/footnote-2.md) +* appraisal of the source code quality by human professionals[3](https://github.com/KilianKegel/CdePkg/blob/master/footnotes/footnote-3.md) + +Since the UEFI "OS" interface (DXE/SHELL/SMM and PEI) can be accessed directly by the compiler-translated sourcecode and UEFI provides an independent set of functions, macros and type definitions, ANSI C and UEFI "OS" specific sourcecode can coexist seamlessly. +This allows a functional ANSI C prototype to adjust successively to real world driver requirements in the UEFI environment. +A UEFI SHELL application might be an intermediate step for this process if the target is a DXE or SMM driver. + +## Intention +**CdePkg** is a feasibility study on how to provide a complete *Hosted Environment* +[(according to ANSI C Specification chapter 5.1.2)](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf#page=23) including all instrisic functions, +which the compiler requires to be a **full featured C-compiler**, in particular the full +set of C-language operators (specifically `/`, `%`, `<<`, `>>` for 64 bit integers) for the 32 bit code generator, needed in PEI. + +Furthermore the questions has to be answered, if UEFI based products can be improved regarding +* software quality (in terms of number of required updates during a life cycle) +* development time +* feature set (complexity and quantity) +* storage space needed in a flash part (the smaller the better) + +...if a standardized programming interface as ANSI C is available, in conjunction with a storage space optimization +strategy, as described below, that splits *wrapper libraries* from *worker drivers*. + +In the UEFI programming environment not even the smallest piece of code can be cross developed on a +different platform, since function names differ in upper/lower case letters, format specifier for +`Print()`-functions differ from C's `printf()`, a `scanf()` counterpart is absent, wideness +of stringtypes differs from corresponding ANSI C functions. + +Since in many cases the ANSI C specification allows freedom for a particular library implementation +(return values, flags, structure layout) but the chosen build and debug environment is VS2019 the original +Microsoft C Library functions had to be recreated, fully compatible, bug for bug (except otherwise noted). +This would provide the most relieable solution for cross development, enable the use of the original +Microsoft header files and prevent from documenting yet another C Library implementation. + +A *Hosted Environment* provides the following obligatory features: +* [`int main(int argc,char **argv)`](https://docs.microsoft.com/en-us/cpp/c-language/main-function-and-program-execution?view=vs-2019) is the driver entry point[4](https://github.com/KilianKegel/CdePkg/blob/master/footnotes/footnote-4.md) +* `argc` and `argv` are used for parameter passing, in **CdePkg** also for POST drivers
https://docs.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments?view=vs-2019 +* full blown ANSI C library +* buffered I/O, that means that [`ungetc()`](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/ungetc-ungetwc?view=vs-2019) works on streams, beside an improvement in speed +* [`exit()`](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/exit-exit-exit?view=vs-2019) invocation on driver termination, that implies + * run [`atexit()`](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/atexit?view=vs-2019)-registered functions + * free allocated memory + * remove all tempfiles (not applicable for POST drivers) + * close open files (not applicable for POST drivers) + +The command line parameter / load options for each *CdePkg*Driver shall be able to be adjusted +on a final system without recompiling the BIOS and updating the BIOS chip. +This e.g. allows the support engineer to change BIOS behaviour on a (partially) +defect system for repair/debug mode, enabling trace messages, excluding special +(non-compliant) devices from beeing enumerated. + +## Implementation +**CdePkg**'s functionality is composed of three components: + 1. the C Library **CdeLib** + 2. the service driver **CdeServices** + 3. the POST command line reference implementation [**CdeLoadOptions**](CdePkg/CdeLoadOptionsDxe) + +all in 32 and 64 bit variants for DXE, SMM and PEI each. + +**CdeLib** and **CdeServices** are highly optimized for space minimized appearance of +ANSI C library functions in the UEFI drivers. This is achieved by implementing all-embracing worker functions + +* `printf()`-family core +* `scanf()`-family core +* `realloc()` core (`malloc()`, `free()`, `realloc()` and `calloc()`) +* `strcmp()`-family core (all `str`/`wcs`/`mem` `n` `i` functions) +* `strcpy()`-family core (all `str`/`wcs`/`mem` `n` functions) +* `strpbrk()`/`strspn()` -family core (all `str`/`wcs` `pbrk`- and `spn`- functions) +* `strtok()`-family core (all `str`/`wcs` `tok`-functions) +* CRT0 startup code for DXE, SMM, PEI +* buffered I/O core (`fread()`, `fwrite()` and `ungetc()`) +* locale character tables +* interface functions to access DXE- and PEI-API + +in the **CdeServices** driver, that resides once in DXE-, SMM- and PEI-phase each. +The **CdeLib** just provides small wrapper functions that invoke **CdeServices**. + +### Interface architecture +![architectural view](archview.png) + +### **CdeLoadOptions** / command line +Each *CdePkg*Driver reports its EfiCallerIdGuid while running through CRT0 to **CdeLoadOptions**. +**CdeLoadOptions** provides a pointer to the matching "Command Line" from an simple EfiCallerIdGuid/CommandLine table +within the file [`CdeLoadOptions.h`](/CdePkg/Include/CdeLoadOptions.h), +compiled into the [**CdeLoadOptions**](CdePkg/CdeLoadOptionsDxe/CdeLoadOptionsDxe.c) driver binary. + +**This is just a proof of concept. In a real implementation, as mentioned above, the command line can be +changed without recompilation and BIOS update.** + +### Boot flow architecture + +The Boot flow sequence consists of: + +1. PEI CdeLoadOption (to provide the commandline to PEI drivers) +2. PEI CdeServices (to provide the space optimized worker functions) +3. PEI custom drivers (CdeServicesPei-based) +4. DXE CdeLoadOption (to provide the commandline to DXE drivers) +5. DXE CdeServices (to provide the space optimized worker functions) +6. DXE custom drivers (CdeServicesDxe-based) +7. BDS custom drivers +8. UEFI Shell drivers (CdeServicesDxe-based, yet still Torito-C-Library-based) + +![bootflow view](CdePkgBootFlow.png) + +## Status +The **CdeLib** and **CdeServices** are derived from their companion project +[Torito C Library](https://github.com/KilianKegel/torito-C-Library) but +split into *wrapper*/*worker* architecture. (Internally [Torito C Library](https://github.com/KilianKegel/torito-C-Library) +was designed from the very beginning for that split architecture, but library and driver were merged into one executable, to +run on platforms without **CdeServices** protocol.) + +The functions below are already implemented and tested, every single one of them, except otherwise noted: + +[List of available functions](implemented.md) + + +[Torito C Library](https://github.com/KilianKegel/torito-C-Library#torito-c-library) has passed extensive +tests to verify Microsoft's C Library compatibility and is also approved in various real world applications. +Therefore the **CdePkg**'s C library will be validated by simple tests only, in the [CdeValidationPkg](CdeValidationPkg/README.md#cdevalidationpkg), for DXE, SMM and PEI respectively. + +### todo +* add simple UART based (COM1) CON I/O interface since consoles are not supported during POST +* add SMM support +* 20190714 add PEI support +* move CRT0 startup code to **CdeServices** +* move local character tables to **CdeServices** +* move buffered I/O core to **CdeServices** +* validate functions in DXE, SMM and PEI [List of available functions](implemented.md#validation-status) +* complete library implementation + +[todo reminder](todoreminder.md) + +## Howto +1. install a build machine: https://github.com/KilianKegel/HowTo-setup-an-UEFI-Development-PC#howto-setup-an-uefi-development-pc + * VS2015x86 tool chain is used. Make sure, that **MSVC v140 VS2015 build tools** are installed +2. `git clone -b CdePkg --recursive https://github.com/tianocore/edk2-staging.git` +3. run **LAUNCH.BAT**, that will + 1. check build tools installed + 2. download NASM and OPENSSL tools + 3. download EDK2 and EDK2-NON-OSI from tianocore and CdeBinPkg + 4. setup the build environment variables +4. build the source tree: + * For MINNOWBOARD BUILD type:
`BLD.bat REL` or `BLD.bat DEB` + * For EMULATION BUILD type:
`BLD.bat EMU` + +5. build the CdeBinPkg source tree:
+* NOTE: CdeBinPkg CdeServices driver and CdeLib library are provided in binary format per default
+but can be recreated within a VS2019 session
+To do so, start CdeBinPkgSrc.sln with VS2019
+ +6. Emulation Build run/debug + * run: `runemu.bat` + * debug: `dbgemu.bat`
+ NOTE: To use `__debugbreak()` the debug engine (VS2019) must be connected to the process *before* + the breakpoint is reached. + +7. Create and debug a new **CdePkg** driver
+ The [CdeValidationPkg](CdeValidationPkg/README.md#cdevalidationpkg) can be used + to create and debug **CdePkg**-based drivers
+ ATTENTION: Only a small number of ANSI C library [functions are yet validated](implemented.md) + +## Related Projects +| related project|annotation| +|:-|:-| +|[Torito C Library](https://github.com/KilianKegel/torito-C-Library#torito-c-library)|C Library for UEFI Shell only. All projects below are built on or derived from *Torito C Library*| +|[Visual ANSI C for UEFI Shell](https://github.com/KilianKegel/Visual-ANSI-C-for-UEFI-Shell#visual-ansi-c-for-uefi-shell)|Getting started with Visual Studio for UEFI Shell and ANSI C cross-development. +|[Visual DOS Tools for UEFI Shell](https://github.com/KilianKegel/Visual-DOS-Tools-for-UEFI-Shell#visual-dos-tools-for-uefi-shell)|more, find command implementation| +|[Visual HWTools for UEFI Shell](https://github.com/KilianKegel/Visual-HWTools-for-UEFI-Shell#visual-hwtools-for-uefi-shell)|HWTools: PCI- and GPIOSpy for Baytrail. MemSpy for all.| + +## Revision history +### 20230910 update CdePkgBlog +* update [**ACPICA port to UEFI**](https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2022-01-16#cdepkgblog-2022-01-16) + +### 2022-01-16 CdePkgBlog +* https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2022-01-16#cdepkgblog-2022-01-16 +### 2021-12-19 CdePkgBlog +* https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2021-12-19#cdepkgblog-2021-12-19 +### 2021-11-28 CdePkgBlog +* https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2021-11-28#cdepkgblog-2021-11-28 +### 2021-11-14 CdePkgBlog +* https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2021-11-14#cdepkgblog-2021-11-14 + +### 20210811 +* force matching commits of `edk2-platforms` and `edk2-non-osi` for EDK2 source `edk2-stable202008` + to prevent build errors +* simplify BUILD batch `BLD.bat` to build for EMULATION, RELEASE and DEBUG + * `BLD.bat EMU` for EMULATION build + * `BLD.bat REL` for MinnowBoard RELEASE build + * `BLD.bat DEB` for MinnowBoard DEBUG build +* add POST Traces [.LOG file](https://raw.githubusercontent.com/tianocore/edk2-staging/CdePkg/UEFIBinaries/RELEASE.log) + +### 20200916 +* update EDK2 source to `edk2-stable202008` + * add to FmpMinnowMaxSystem.dsc, FmpBlueSampleDevice.dsc, FmpGreenSampleDevice.dsc, FmpRedSampleDevice.dsc `[LibraryClasses.common]` to prevent build failure: + * ` FmpDependencyLib|FmpDevicePkg\Library\FmpDependencyLib\FmpDependencyLib.inf` + * ` FmpDependencyCheckLib|FmpDevicePkg\Library\FmpDependencyCheckLibNull\FmpDependencyCheckLibNull.inf` + * ` FmpDependencyDeviceLib|FmpDevicePkg\Library\FmpDependencyDeviceLibNull\FmpDependencyDeviceLibNull.inf` + +### 20200712 +* update EDK2 source to `edk2-stable202005` +* fix ["Error 4000" EDK II Build Issue ](https://edk2.groups.io/g/devel/message/62295?p=,,,20,0,0,0::Created,,4000,20,2,0,75394040) + * add to PlatformPkgX64.dsc `[LibraryClasses.common]` to prevent build failure: + * ` FmpDependencyLib|FmpDevicePkg\Library\FmpDependencyLib\FmpDependencyLib.inf` + * ` FmpDependencyCheckLib|FmpDevicePkg\Library\FmpDependencyCheckLibNull\FmpDependencyCheckLibNull.inf` + * ` FmpDependencyDeviceLib|FmpDevicePkg\Library\FmpDependencyDeviceLibNull\FmpDependencyDeviceLibNull.inf` +* add workaround for suddenly disappeared `https://indy.fulgan.com/SSL/openssl-1.0.2r-x64_86-win64.zip` + +### 20191202 +* add ASSERT.H and LOCALE.H function validation for EmulationMode and MinnowBoard for PEI and DXE POST drivers +* assert(), setlocale(), localeconv() + +### 20191129 +* add CTYPE.H and WCTYPE.H function validation for EmulationMode and MinnowBoard for PEI and DXE POST drivers +* isalnum(),isalpha(),iscntrl(),isdigit(),isgraph(),islower(),isprint(),ispunct(),isspace(),isupper(),isxdigit(),tolower(),toupper() +* iswalnum(),iswalpha(),iswblank(),iswcntrl(),iswdigit(),iswgraph(),iswlower(),iswprint(),iswpunct(),iswspace(),iswupper(),iswxdigit(),iswctype(),wctype(),towlower(),towupper(),towctrans(),wctrans() + +### 20191127 +* add STDLIB.H function validation for EmulationMode and MinnowBoard for PEI and DXE POST drivers +* atoi(), atol(), strtol(), strtoul(), rand(), srand(), calloc(), free(), malloc(), realloc(), atexit(), exit(), qsort(), abs(), labs(), div(), ldiv() +* not available for POST drivers: abort(), strtod(), atof(), getenv(), system(), bsearch() + +### 20191126 +* add STDIO.H function validation for EmulationMode and MinnowBoard for PEI and DXE POST drivers +* tmpnam(), printf(), snprintf(), sprintf(), vsnprintf(), vsscanf(), sscanf(), vprintf(), vsprintf() +* NOTE: file access and locale dependent functions are not available for POST drivers. + +### 20191125 +* add WCHAR.H function validation for EmulationMode and MinnowBoard for PEI and DXE POST drivers +* wprintf(), swprintf(), vswprintf(), wcscpy(), wcsncpy(), wcscat(), wcsncat(), wcscmp(), wcsncmp(), + wcschr(), wcscspn(), wcspbrk(), wcsrchr(), wcsspn(), wcsstr(), wcstok(), wcslen(), + wmemcmp(), wmemcpy(), wmemmove(), wmemset() +* NOTE: file access and "locale" dependent functions are not available for POST drivers. + +### 20191119 +* add STRING.H function validation for EmulationMode and MinnowBoard
+ memcpy(), memmove(), strcpy(), strncpy(), strcat(), strncat(), memcmp(), strcmp() + strncmp(), memchr(), strchr(), strcspn(), strpbrk(), strrchr(), strspn(), strstr() + strtok(), memset(), strerror() and strlen() +* not implemented are strcoll() and strxfrm() that are locale dependant that + is not yet supported + +### 20191111 +* add all remaining TIME.H function validation for EmulationMode and MinnowBoard
+ difftime(), mktime(), time(), asctime(), ctime(), gmtime(), localetime(), strftime() +* TIME.H functions are fully available for UEFI POST (PEI and DXE) + +### 20191108 +* add TIME_H\clock() function validation for EmulationMode and MinnowBoard +* add Torito C Library sourcecode selection to build **CdePkg** driver and libraries + +### 20191028 +* update to meet offical EDK2-STAGING requirements + * remove binary driver + * remove binary library + * simplify PACKAGE_PATH related components + +### 20191023 +* initial revision diff --git a/UEFIBinaries/DEBUG.bin b/UEFIBinaries/DEBUG.bin new file mode 100644 index 00000000000..c92bbee36e6 Binary files /dev/null and b/UEFIBinaries/DEBUG.bin differ diff --git a/UEFIBinaries/DEBUG.log b/UEFIBinaries/DEBUG.log new file mode 100644 index 00000000000..2c4b944b192 --- /dev/null +++ b/UEFIBinaries/DEBUG.log @@ -0,0 +1,5712 @@ + +>>>>SecStartup + +Mono Status Code PEIM Loaded +Install PPI: 1F4C6F90-B06B-48D8-A201-BAE5F1CD7D56 +Install PPI: AB294A92-EAF5-4CF3-AB2B-2D4BED4DB63D +Register PPI Notify: F894643D-C449-42D1-8EA8-85BDD8C65BDE +GGC: 0x00000210 GMSsize:0x00000002 +DetermineTurbotBoard() Entry +MmioConf0[0xFED0E200], MmioPadval[0xFED0E208] +Gpio_S5_4 value is 0x3 +I'm MinnowBoard Turbot! +CheckCfioPnpSettings: CFIO Pnp Settings Disabled +Setting BootMode to BOOT_WITH_FULL_CONFIGURATION +Setup MMIO size ... + +Install PPI: E767BF7F-4DB6-5B34-1011-4FBE4CA7AFD2 +PROGRESS CODE: V3020003 I0 +Loading PEIM E4CEDF93-672A-4782-A7FD-5FC6D239377D +Loading PEIM at 0x000FFFA9320 EntryPoint=0x000FFFA963D SeCUma.efi +PROGRESS CODE: V3020002 I0 +Install PPI: CBD86677-362F-4C04-9459-A741326E05CF +Info: SeC PPI load sucessfully +PROGRESS CODE: V3020003 I0 +Loading PEIM C779F6D8-7113-4AA1-9648-EB1633C7D53B +Loading PEIM at 0x000FFFAB0A0 EntryPoint=0x000FFFAB49C CapsulePei.efi +PROGRESS CODE: V3020002 I0 +Install PPI: 3ACF33EE-D892-40F4-A2FC-3854D2E1323D +PROGRESS CODE: V3020003 I0 +Loading PEIM D9F5B28C-9FF1-47D6-B503-3DC23BD345FF +Loading PEIM at 0x000FFFB36A0 EntryPoint=0x000FFFB38E0 PchEarlyInitPeim.efi +PROGRESS CODE: V3020002 I0 +PROGRESS CODE: V3020003 I0 +Loading PEIM D4EE25EA-0B48-43AE-A016-4D6E8B6C43B3 +Loading PEIM at 0x000FFFB7220 EntryPoint=0x000FFFB7540 MemoryInit.efi +PROGRESS CODE: V3020002 I0 +Reg_EFF_DualCH_EN = 0x100301C0. +Buffer size brefore add 165B, after adjust 1668. +MRC Parameters not valid. status is 8000000E +Set MRC paramaters for MinnowBoard Max. +MmioConf0[0xFED0E220], MmioPadval[0xFED0E228] +Gpio_S5_5 value is 0x3 +Determine the memory size is [2GB] +DRAM_Speed is 1333MHz! +DRAM_Speed is type 2, EccEnabled = 0 +tCL = 9 +tRP_tRCD = 9 +tWR = 10 +tWTR = 5 +tRRD = 5 +tRTP = 5 +tFAW = 30 +PROGRESS CODE: V51001 I0 +POSTCODE=<0024> +MRC getting memory size from SeC ... +SeC Device ID: F18 +Error: SeC exclusion error +Error: No HECI command send +MRC SeCUmaSize memory size from SeC ... 0 +MRC getting fTPM memory size from SeC ... +MRC SeCfTPMUmaSize memory size from SeC ... 0 +PROGRESS CODE: V51002 I0 +POSTCODE=<0025> +PROGRESS CODE: V51003 I0 +POSTCODE=<0027> +Configuring Memory... +CheckMicrocodeRevision = 00000909, CpuId = 00030679 +####: ConfigureMemory() Entry +Current function is McEnableHPET + Current function is ClearSelfRefresh + Current function is OemTrackInitComplete + Current function is ProgSFRVolSel + Current function is ProgDdrTimingControl + Current function is ProgBunit + Current function is ProgMpllSetup + Current function is ProgStaticDdrSetup + Current function is ProgStaticInitPerf + Current function is ProgStaticPwrClkGating + Current function is DUnitBlMode + Current function is ControlDDR3Reset + Current function is EnableVreg + Current function is ProgHmc + Current function is ProgReadWriteFifoPtr + Current function is ProgComp + Current function is SetIOBUFACT + Current function is ProgDdecodeBeforeJedec + Current function is PerformDDR3Reset + Current function is PreJedecInit + Current function is PerformJedecInit + Current function is SetDDRInitializationComplete + Current function is PerformJedecInit + Current function is DisableRank2RankSwitching + Current function is MMRC_RcvnTrain + Current function is MMRC_WrLvlFineTrain + Current function is MMRC_WrLvlCoarseTrain + Current function is MMRC_RdVrefTrain + Current function is MMRC_RdTrain + Current function is MMRC_WrTrain + Current function is MMRC_PerformanceSetting + Current function is MMRC_PowerGatingSetting + Current function is MMRC_SearchRmt + START_RMT: + RxDqLeft RxDqRight RxVLow RxVHigh TxDqLeft TxDqRight CmdLeft CmdRight +------------------------------------------------------------------------------------------------ +Channel 0 Rank 0 -22 22 -22 18 -25 25 0 0 +STOP_RMT: +CMD module is per channel only and without Rank differentiation +Current function is ProgDraDrb + Current function is ProgMemoryMappingRegisters + Current function is ProgDdrControl + Current function is SetScrambler + Current function is ChangeSelfRefreshSetting + Current function is SetInitDone + Current function is McDisableHPET + Current function is FillOutputStructure + MRC INIT DONE +PlatformInfo MemData content. +MemConfigSize = 0x0000165B +DdrFreq = 0x00000002 +DdrType = 0x00000001 +EccSupport = 0x00000000 +MemSize = 0x00000800 +MRC allocating memory for SeC ... +SeC Device ID: F18 +Entered SeC DRAM Init Done procedure. +Install EFI Memory. +Fail to Get MemoryOverwriteRequestControl Variable +SmramHobDescriptorBlock->Descriptor[1].PhysicalStart = 7B001000 +SmramHobDescriptorBlock->Descriptor[1].CpuStart = 7B001000 +PeiInstallPeiMemory MemoryBegin 0x71000000, MemoryLength 0xA000000 +Save MRC params. +PROGRESS CODE: V30F100B I0 +MemoryInit Installed. +>>>>MemoryInit Done +PROGRESS CODE: V3020003 I0 +Temp Stack : BaseAddress=0xFEF8C400 Length=0x3C00 +Temp Heap : BaseAddress=0xFEF80000 Length=0xC400 +Total temporary memory: 65536 bytes. + temporary memory stack ever used: 15360 bytes. + temporary memory heap used for HobList: 8864 bytes. + temporary memory heap occupied by memory pages: 0 bytes. +Old Stack size 15360, New stack size 131072 +Stack Hob: BaseAddress=0x71000000 Length=0x20000 +Heap Offset = 0x8DF60000 Stack Offset = 0x8DF70000 +Loading PEIM 52C05B14-0B98-496C-BC3B-04B50211D680 +Loading PEIM at 0x0007AFF7000 EntryPoint=0x0007AFF7355 PeiCore.efi +Reinstall PPI: 8C8CE578-8A3D-4F1C-9935-896185C32DD3 +Reinstall PPI: 5473C07A-3DCB-4DCA-BD6F-1E9689E7349A +Reinstall PPI: B9E0ABFE-5979-4914-977F-6DEE78C278A6 +Install PPI: F894643D-C449-42D1-8EA8-85BDD8C65BDE +Notify: PPI Guid: F894643D-C449-42D1-8EA8-85BDD8C65BDE, Peim notify entry point: FFFA676E +Install PPI: 49EDB1C1-BF21-4761-BB12-EB0031AABB39 +Notify: PPI Guid: 49EDB1C1-BF21-4761-BB12-EB0031AABB39, Peim notify entry point: FFF9A286 +The 1th FV start address is 0x0007AFA7000, size is 0x00050000, handle is 0x7AFA7000 +Install PPI: 49EDB1C1-BF21-4761-BB12-EB0031AABB39 +Notify: PPI Guid: 49EDB1C1-BF21-4761-BB12-EB0031AABB39, Peim notify entry point: FFF9A286 +The 2th FV start address is 0x0007AD77000, size is 0x00220000, handle is 0x7AD77000 +Found firmware volume Image File 7AD77048 in FV[2] 7AD77000 +Loading PEIM 9B3ADA4F-AE56-4C24-8DEA-F03B7558AE50 +Loading PEIM at 0x0007AD74000 EntryPoint=0x0007AD74315 PcdPeim.efi +PROGRESS CODE: V3020002 I0 +Install PPI: 06E81C58-4AD7-44BC-8390-F10265F72480 +Install PPI: 01F34D25-4DE2-23AD-3FF3-36353FF323F1 +Install PPI: 4D8B155B-C059-4C8F-8926-06FD4331DB8A +Install PPI: A60C6B59-E459-425D-9C69-0BCC9CB27D81 +Register PPI Notify: 605EA650-C65C-42E1-BA80-91A52AB618C6 +PROGRESS CODE: V3020003 I0 +Reinstall PPI: 06E81C58-4AD7-44BC-8390-F10265F72480 +Reinstall PPI: 4D8B155B-C059-4C8F-8926-06FD4331DB8A +Reinstall PPI: 01F34D25-4DE2-23AD-3FF3-36353FF323F1 +Reinstall PPI: A60C6B59-E459-425D-9C69-0BCC9CB27D81 +DiscoverPeimsAndOrderWithApriori(): Found 0xB PEI FFS files in the 1th FV +Loading PEIM 0A5EA2E1-BE0B-44A0-A775-F429C9A018A0 +Loading PEIM at 0x0007AD6D000 EntryPoint=0x0007AD6D315 PlatformEarlyInit.efi +PROGRESS CODE: V3020002 I0 +Install PPI: 63B6E435-32BC-49C6-81BD-B7A1A0FE1A6C +Install PPI: 1F4C6F90-B06B-48D8-A201-BAE5F1CD7D56 +Install PPI: 30AC275E-BB30-4B84-A1CD-0AF1322C89C0 +PlatformFlavor is 1 (3=tablet,1=mobile,2=desktop) +MultiPlatformGpioTableInit()... +MultiPlatformGpioProgram()... +Start to config Minnow2 GPIO pins +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C550, Set PAD_VAL = 0x00000002, Set CONF0 = 0x2003CC01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C590, Set PAD_VAL = 0x00000002, Set CONF0 = 0x2003CC01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C5D0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 2, MMIO Base = 0xFED0C600, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CA81 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 2, MMIO Base = 0xFED0C630, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CA81 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 2, MMIO Base = 0xFED0C660, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CA81 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C620, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 255, Func# = 2, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C650, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC02 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C220, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C250, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C240, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C260, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C270, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C230, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C280, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C540, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C3E0, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C3D0, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C400, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C3B0, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C360, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C380, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C3C0, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C370, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C3F0, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C390, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C330, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C320, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C350, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C2F0, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C340, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C310, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C300, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003EC00 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C2B0, Set PAD_VAL = 0x00000002, Set CONF0 = 0x20038C01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C2E0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x20038C01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C290, Set PAD_VAL = 0x00000003, Set CONF0 = 0x20038C01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C2D0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x20038C01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C2A0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x20038C01 +Usage = 255, Func# = 1, IntType = 6, Pull Up/Down = 6, MMIO Base = 0xFED0C3A0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2603CC01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C2C0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x20038C01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C5F0, Set PAD_VAL = 0x00000002, Set CONF0 = 0x2003CC01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C690, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC01 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C460, Set PAD_VAL = 0x00000000, Set CONF0 = 0x20038C00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C440, Set PAD_VAL = 0x00000000, Set CONF0 = 0x20038C00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C430, Set PAD_VAL = 0x00000000, Set CONF0 = 0x20038C00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C420, Set PAD_VAL = 0x00000000, Set CONF0 = 0x20038C00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C450, Set PAD_VAL = 0x00000001, Set CONF0 = 0x20038C00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C470, Set PAD_VAL = 0x00000000, Set CONF0 = 0x20038C00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C410, Set PAD_VAL = 0x00000000, Set CONF0 = 0x20038C00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C480, Set PAD_VAL = 0x00000001, Set CONF0 = 0x20038C00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C560, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C5A0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C580, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 2, MMIO Base = 0xFED0C5C0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CA81 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C670, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C4D0, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C4F0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2083CC80 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C4E0, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C510, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 4, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C500, Set PAD_VAL = 0x00000005, Set CONF0 = 0x2003CC00 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C0D0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C0C0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2083CC80 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C0F0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C0E0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2083CC80 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C110, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C120, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C130, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C100, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C020, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C010, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C000, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C040, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C060, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C070, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C090, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C080, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C210, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C200, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C1F0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C1E0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC01 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C1D0, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C1B0, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C190, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C1C0, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C1A0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C170, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C150, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C140, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C180, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0C160, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC81 +Usage = 0, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C050, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC01 +Usage = 4, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C030, Set PAD_VAL = 0x00000004, Set CONF0 = 0x2003CC01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 1, MMIO Base = 0xFED0C0A0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CD01 +Usage = 255, Func# = 1, IntType = 0, Pull Up/Down = 1, MMIO Base = 0xFED0C0B0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CD01 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C6A0, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C570, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C5B0, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C680, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C610, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0C640, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 255, Func# = 2, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D130, Set PAD_VAL = 0x00000002, Set CONF0 = 0x2003CC02 +Usage = 255, Func# = 2, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D120, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2083CC02 +Usage = 255, Func# = 2, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D110, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC02 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D140, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D150, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D160, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 255, Func# = 2, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D180, Set PAD_VAL = 0x00000002, Set CONF0 = 0x2003CC02 +Usage = 255, Func# = 2, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D190, Set PAD_VAL = 0x00000002, Set CONF0 = 0x2003CC02 +Usage = 255, Func# = 2, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D170, Set PAD_VAL = 0x00000002, Set CONF0 = 0x2003CC02 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D100, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D0E0, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D0F0, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 4, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D0C0, Set PAD_VAL = 0x00000004, Set CONF0 = 0x2003CC00 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 3, MMIO Base = 0xFED0D1A0, Set PAD_VAL = 0x00000002, Set CONF0 = 0x2003CB00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D1B0, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D010, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D040, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D080, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D0B0, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D000, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D030, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D060, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D0A0, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D0D0, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D020, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D050, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0D090, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0E1D0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0E210, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0E1E0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 255, Func# = 6, IntType = 5, Pull Up/Down = 4, MMIO Base = 0xFED0E1F0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2503C886 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E200, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E220, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC00 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E240, Set PAD_VAL = 0x00000002, Set CONF0 = 0x2003CC00 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E230, Set PAD_VAL = 0x00000002, Set CONF0 = 0x2003CC00 +Usage = 4, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0E260, Set PAD_VAL = 0x00000005, Set CONF0 = 0x2003CC00 +Usage = 4, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0E250, Set PAD_VAL = 0x00000005, Set CONF0 = 0x2003CC00 +Usage = 4, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E120, Set PAD_VAL = 0x00000005, Set CONF0 = 0x2003CC00 +Usage = 255, Func# = 0, IntType = 0, Pull Up/Down = 2, MMIO Base = 0xFED0E070, Set PAD_VAL = 0x00000002, Set CONF0 = 0x2003CA80 +Usage = 255, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E0B0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC00 +Usage = 255, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E140, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC00 +Usage = 4, Func# = 1, IntType = 0, Pull Up/Down = 2, MMIO Base = 0xFED0E110, Set PAD_VAL = 0x00000004, Set CONF0 = 0x2003CC01 +Usage = 255, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0E010, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 255, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0E080, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 0, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E0A0, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC01 +Usage = 4, Func# = 1, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E130, Set PAD_VAL = 0x00000005, Set CONF0 = 0x2003CC01 +Usage = 255, Func# = 0, IntType = 0, Pull Up/Down = 2, MMIO Base = 0xFED0E0C0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CA80 +Usage = 255, Func# = 0, IntType = 0, Pull Up/Down = 2, MMIO Base = 0xFED0E000, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CA80 +Usage = 255, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E020, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003EC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E170, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E270, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E1C0, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E1B0, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E160, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0E150, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0E180, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0E190, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 2, Func# = 0, IntType = 0, Pull Up/Down = 0, MMIO Base = 0xFED0E1A0, Set PAD_VAL = 0x00000003, Set CONF0 = 0x2003CC80 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E330, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E380, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E360, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E310, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E370, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E300, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E390, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E320, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E3A0, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E340, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E350, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E3B0, Set PAD_VAL = 0x00000001, Set CONF0 = 0x2003CC00 +Usage = 0, Func# = 0, IntType = 0, Pull Up/Down = 6, MMIO Base = 0xFED0E280, Set PAD_VAL = 0x00000000, Set CONF0 = 0x2003CC00 +ACPI Wake Status Register: 0001 +ACPI Wake Event Data: 02 +Setting BootMode to BOOT_WITH_FULL_CONFIGURATION +PlatformEarlyInitEntry: Setup Variable does not exist. +PlatformEarlyInitEntry: Set PcdNvStoreDefaultId to STANDARD +Setup Option ISPEn: 0x1 +Setup Option ISPDevSel: 0x1 +Install PPI: 7D84B2C2-22A1-4372-B12C-EBB232D3A6A3 +ConfigureSoCGpio------------start +Auto detection mode------------start +SOC B0 and later: eMMC 4.5 GPIO Configuration +ConfigureSoCGpio------------end +ConfigureLpssAndSccGpio------------start +LpssHsuart0FlowControlEnabled[0] +LpssHsuart1FlowControlEnabled[0] +ConfigureLpssAndSccGpio------------end +ConfigureLpeGpio------------start +ConfigureLpeGpio------------end +PlatformSsaInit() - Start +PlatformSsaInit() - SystemConfiguration->ISPDevSel 0x1 +PlatformSsaInit() - Device 2 Interrupt Route Done +PchPolicySetupInit() - Start +Install PPI: 15344673-D365-4BE2-8513-1497CC07611D +PchPolicySetupInit() - End +Install PPI: 7408D748-FC8C-4EE6-9288-C4BEC092A410 +Install PPI: EF398D58-9DFD-4103-BF94-78C6F4FE712F +Notify: PPI Guid: 7408D748-FC8C-4EE6-9288-C4BEC092A410, Peim notify entry point: FFFA1C4D +InstallPlatformClocksNotify()... +Register PPI Notify: 9CA93627-B65B-4324-A202-C0B461764543 +InstallPlatformSysCtrlGPIONotify()... +Register PPI Notify: 9CA93627-B65B-4324-A202-C0B461764543 +Register PPI Notify: 605EA650-C65C-42E1-BA80-91A52AB618C6 +Register PPI Notify: F894643D-C449-42D1-8EA8-85BDD8C65BDE +Notify: PPI Guid: F894643D-C449-42D1-8EA8-85BDD8C65BDE, Peim notify entry point: 7AD6E9E5 +Reset cache attribute and disable CAR. +Base=FF800005, Mask=FFF800800 +Base=6, Mask=FC0000800 +Base=40000006, Mask=FE0000800 +Base=60000006, Mask=FF0000800 +Base=70000006, Mask=FF8000800 +Base=78000006, Mask=FFC000800 +Base=7BE00000, Mask=FFFE00800 +MTRR Settings: +============= +MTRR Default Type: 0000000000000C00 +Fixed MTRR[00] : 0606060606060606 +Fixed MTRR[01] : 0606060606060606 +Fixed MTRR[02] : 0505050505050505 +Fixed MTRR[03] : 0505050505050505 +Fixed MTRR[04] : 0505050505050505 +Fixed MTRR[05] : 0505050505050505 +Fixed MTRR[06] : 0505050505050505 +Fixed MTRR[07] : 0505050505050505 +Fixed MTRR[08] : 0505050505050505 +Fixed MTRR[09] : 0505050505050505 +Fixed MTRR[10] : 0505050505050505 +Variable MTRR[00]: Base=00000000FF800005 Mask=0000000FFF800800 +Variable MTRR[01]: Base=0000000000000006 Mask=0000000FC0000800 +Variable MTRR[02]: Base=0000000040000006 Mask=0000000FE0000800 +Variable MTRR[03]: Base=0000000060000006 Mask=0000000FF0000800 +Variable MTRR[04]: Base=0000000070000006 Mask=0000000FF8000800 +Variable MTRR[05]: Base=0000000078000006 Mask=0000000FFC000800 +Variable MTRR[06]: Base=000000007BE00000 Mask=0000000FFFE00800 + +Memory Ranges: +==================================== +WB:0000000000000000-000000000009FFFF +WP:00000000000A0000-00000000000FFFFF +WB:0000000000100000-000000007BDFFFFF +UC:000000007BE00000-00000000FF7FFFFF +WP:00000000FF800000-00000000FFFFFFFF +UC:0000000100000000-0000000FFFFFFFFF +Build Hob from default +RootComplexBar : 0xFED1C000 +PmcBase : 0xFED03000 +IoBase : 0xFED0C000 +IlbBase : 0xFED08000 +SpiBase : 0xFED01000 +MphyBase : 0xFEF00000 +LOCAL_APIC_ADDRESS : 0xFEE00000 +IO_APIC_ADDRESS : 0xFEC00000 +PciExpressBase : 0xE0000000 +FLASH_BASE_ADDRESS : 0xFF800000 +PROGRESS CODE: V3020003 I0 +Loading PEIM D82D57AC-99F9-4C7A-B591-BBCF8A0E7FBE +Loading PEIM at 0x0007AD6B000 EntryPoint=0x0007AD6B315 PchSmbusArpDisabled.efi +PROGRESS CODE: V3020002 I0 +InitializePchSmbusPeim() Start +Install PPI: 9CA93627-B65B-4324-A202-C0B461764543 +Notify: PPI Guid: 9CA93627-B65B-4324-A202-C0B461764543, Peim notify entry point: 7AD6F804 +PlatformInfo protocol is working in ConfigurePlatformClocks()...1 +PEI SmbusExecute() Start, SmbusDeviceAddress=D2, Command=87, Operation=4 +PEI SmbusExecute() End +Clock Generator CK505 Not Present, vendor ID on board is 0 +Notify: PPI Guid: 9CA93627-B65B-4324-A202-C0B461764543, Peim notify entry point: 7AD6F9D9 +ConfigurePlatformSysCtrlGpio()... +Platform Flavor | Board ID = 0x1 | 0xB0 +Register PPI Notify: F894643D-C449-42D1-8EA8-85BDD8C65BDE +Notify: PPI Guid: F894643D-C449-42D1-8EA8-85BDD8C65BDE, Peim notify entry point: 7AD6B56B +InitializePchSmbusPeim() End +PROGRESS CODE: V3020003 I0 +Loading PEIM FD236AE7-0791-48C4-B29E-29BDEEE1A838 +Loading PEIM at 0x0007AD65000 EntryPoint=0x0007AD65315 PchInitPeim.efi +PROGRESS CODE: V3020002 I0 +InstallPchInitPpi()-Start +PmcBase needs to be programmed and enabled before here. +Register PPI Notify: 15344673-D365-4BE2-8513-1497CC07611D +Register PPI Notify: F894643D-C449-42D1-8EA8-85BDD8C65BDE +Notify: PPI Guid: 15344673-D365-4BE2-8513-1497CC07611D, Peim notify entry point: 7AD666ED +PchInitialize() - Start +PchInitInterrupt () - Start +PchInitInterrupt () - End +PchMiscInit() - Start +PchMiscInit() - End +PchIoApicInit() - Start +PchIoApicInit() - End +PchPeimEhciPllCfg() SystemConfiguration->EhciPllCfgEnable = 0x1 +PchPeimEhciPllCfg() R_IOSF_SPXB_CH1CTRL = 0x1 +PchPeimEhciPllCfg() R_IOSF_SPXB_PORTCTL0 = 0x1 +PchPeimEhciPllCfg() R_IOSF_SPXB_PORTCTL1 = 0x2 +PchPeimEhciPllCfg() R_IOSF_SPXB_PORTCTL2 = 0x0 +PchPeimEhciPllCfg() R_IOSF_SPXB_PMCTL = 0x9E +PchUsbInit() - Start +PchUsbInit() - End +Install PPI: ACB93B08-5CDC-4A8F-93D4-06E342DF182E +PchInitialize() - End +Notify: PPI Guid: F894643D-C449-42D1-8EA8-85BDD8C65BDE, Peim notify entry point: 7AD65F39 +PchSataInit() - Start +PchSataInit() - End +InstallPchInitPpi() - End +PROGRESS CODE: V3020003 I0 +Loading PEIM AA652CB9-2D52-4624-9FAE-D4E58B67CA46 +Loading PEIM at 0x0007AD62000 EntryPoint=0x0007AD62315 PchSpiPeim.efi +PROGRESS CODE: V3020002 I0 +InstallPchSpi() Start +Install PPI: A38C6898-2B5C-4FF6-9326-2E63212E56C2 +SPI PPI Installed +InstallPchSpi() End +PROGRESS CODE: V3020003 I0 +Loading PEIM B4E0CDFC-30CD-4B29-A445-B0AA95A532E4 +Loading PEIM at 0x0007AD60000 EntryPoint=0x0007AD60315 PeiSmmAccess.efi +PROGRESS CODE: V3020002 I0 +Install PPI: 268F33A9-CCCD-48BE-8817-86053AC32ED6 +PROGRESS CODE: V3020003 I0 +Loading PEIM FF456B9C-0DC7-4682-9E92-0DE84B6E4067 +Loading PEIM at 0x0007AD5E000 EntryPoint=0x0007AD5E315 PeiSmmControl.efi +PROGRESS CODE: V3020002 I0 +Install PPI: 61C68702-4D7E-4F43-8DEF-A74305CE74C5 +PROGRESS CODE: V3020003 I0 +Loading PEIM 89E549B0-7CFE-449D-9BA3-10D8B2312D71 +Loading PEIM at 0x0007AD5B000 EntryPoint=0x0007AD5B3C5 S3Resume2Pei.efi +PROGRESS CODE: V3020002 I0 +Install PPI: 6D582DBC-DB85-4514-8FCC-5ADF6227B147 +PROGRESS CODE: V3020003 I0 +Loading PEIM 1C8B7F78-1699-40E6-AF33-9B995D16B043 +Loading PEIM at 0x0007AD59000 EntryPoint=0x0007AD59315 PiSmmCommunicationPei.efi +PROGRESS CODE: V3020002 I0 +PROGRESS CODE: V3020003 I0 +Loading PEIM 86D70125-BAA3-4296-A62F-602BEBBB9081 +Loading PEIM at 0x0007AD54000 EntryPoint=0x0007AD543F6 DxeIpl.efi +PROGRESS CODE: V3020002 I0 +PROGRESS CODE: V3020003 I0 +Install PPI: EE4E5898-3914-4259-9D6E-DC7BD79403CF +Install PPI: A31280AD-481E-41B6-95E8-127F4C984779 +Install PPI: 1A36E4E7-FAB6-476A-8E75-695A0576FDD7 +Install PPI: 0AE8CE5D-E448-4437-A8D7-EBF5F194F731 +DiscoverPeimsAndOrderWithApriori(): Found 0x1 PEI FFS files in the 2th FV +Customized Guided section Memory Size required is 0x9BC010 and address is 0x7A387000 +ProcessFvFile() FV at 0x7A387010, FvAlignment required is 0x10 +Install PPI: EA7CA24B-DED5-4DAD-A389-BF827E8F9B38 +Notify: PPI Guid: EA7CA24B-DED5-4DAD-A389-BF827E8F9B38, Peim notify entry point: FFF9A286 +The 3th FV start address is 0x0007A387010, size is 0x009BC000, handle is 0x7A387010 +Install PPI: 49EDB1C1-BF21-4761-BB12-EB0031AABB39 +Notify: PPI Guid: 49EDB1C1-BF21-4761-BB12-EB0031AABB39, Peim notify entry point: FFF9A286 +The FV 7A387010 has already been processed! +DiscoverPeimsAndOrderWithApriori(): Found 0x0 PEI FFS files in the 3th FV +Loading PEIM CDE000FF-6D26-4A97-92CB-28C113B0D4EA +Loading PEIM at 0x0007A385000 EntryPoint=0x0007A385579 cdeWelcomePei.efi +PROGRESS CODE: V3020002 I0 +POSTCODE=<3A20> +Install PPI: CDE000FF-6D26-4A97-92CB-28C113B0D4EA + + +---------------- +cdeWelcomePei//a:\edk2-staging2021-12-19\CdePkg\CdeWelcome\main.c(78): INTRODUCTION: "CDETRACE" macro. -> + Parameters are typechecked at build time by compilers from GNU, MICROSOFT and others during 2015 to 2021 +Printing 256 bytes of initilaized memory in a "dump"-format: +0000: 00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F +0010: 10 11 12 13 14 15 16 17 - 18 19 1A 1B 1C 1D 1E 1F +0020: 20 21 22 23 24 25 26 27 - 28 29 2A 2B 2C 2D 2E 2F +0030: 30 31 32 33 34 35 36 37 - 38 39 3A 3B 3C 3D 3E 3F +0040: 40 41 42 43 44 45 46 47 - 48 49 4A 4B 4C 4D 4E 4F +0050: 50 51 52 53 54 55 56 57 - 58 59 5A 5B 5C 5D 5E 5F +0060: 60 61 62 63 64 65 66 67 - 68 69 6A 6B 6C 6D 6E 6F +0070: 70 71 72 73 74 75 76 77 - 78 79 7A 7B 7C 7D 7E 7F +0080: 80 81 82 83 84 85 86 87 - 88 89 8A 8B 8C 8D 8E 8F +0090: 90 91 92 93 94 95 96 97 - 98 99 9A 9B 9C 9D 9E 9F +00A0: A0 A1 A2 A3 A4 A5 A6 A7 - A8 A9 AA AB AC AD AE AF +00B0: B0 B1 B2 B3 B4 B5 B6 B7 - B8 B9 BA BB BC BD BE BF +00C0: C0 C1 C2 C3 C4 C5 C6 C7 - C8 C9 CA CB CC CD CE CF +00D0: D0 D1 D2 D3 D4 D5 D6 D7 - D8 D9 DA DB DC DD DE DF +00E0: E0 E1 E2 E3 E4 E5 E6 E7 - E8 E9 EA EB EC ED EE EF +00F0: F0 F1 F2 F3 F4 F5 F6 F7 - F8 F9 FA FB FC FD FE FF +3s... 2s... 1s... 0s... +PROGRESS CODE: V3020003 I0 +Loading PEIM CDE00011-3212-4114-8E7E-7BDE2BFE14BC +Loading PEIM at 0x0007A381000 EntryPoint=0x0007A381320 CdeLoadOptionsPei.efi +PROGRESS CODE: V3020002 I0 +Install PPI: CDE00000-2C09-4284-90F9-9A988ABDF6FB +PROGRESS CODE: V3020003 I0 +Loading PEIM 24169E35-2454-4940-92BC-82321A2C7562 +Loading PEIM at 0x0007A37E000 EntryPoint=0x0007A37E31D VlvInitPeim.efi +PROGRESS CODE: V3020002 I0 +VlvInitPeiEntryPoint start.... + +------------------------ VLV SSA Platform Policy dump Begin --------------- +Graphics Configuration: + GttSize : 2 MB + IgdDvmt50PreAlloc : 2 + PrimaryDisplay : 0 + ApertureSize : 2 + Turbo Enable : 1 + +------------------------ VLV SSA Platform Policy dump END ----------------- +ProgramEcBase Done.... +SSASafeConfiguration Done.... +Clear Dbuff to all zero before read 0xFFFFFFFF +PUNIT_ISPSSPM0 value is 0x3000003 +ISP Device is enabled by fuse +Iunit Configuration - Start +Default Iunit configure as B0D2F0 +Re-Configuring Iunit as B0D2F0 +Iunit Configuration - End +InitThermalRegisters Done.... +IGD enabled. +IGD Turbo Enable. +PUNIT_BIOS_CONFIG11 = 0x100301C0. +PUNIT_BIOS_CONFIG22 = 0x10030140. +TotalMmioLength: 0x10508000 bytes +GraphicsInit Done.... +ProgramGpioNC Done.... +Install PPI: 09EA8911-BE0D-4230-A003-EDC693B48E11 +Install mVlvPeiInitPpi Done.... +PROGRESS CODE: V3020003 I0 +DXE IPL Entry +Loading PEIM D6A2CB7F-6A18-4E2F-B43B-9920A733700A +Loading PEIM at 0x0007A359000 EntryPoint=0x0007A359BF4 DxeCore.efi +PROGRESS CODE: V3021001 I0 +Loading DXE CORE at 0x0007A359000 EntryPoint=0x0007A359BF4 +AddressBits=36 5LevelPaging=0 1GPage=0 +Pml5=1 Pml4=1 Pdp=64 TotalPage=66 +Install PPI: 605EA650-C65C-42E1-BA80-91A52AB618C6 +Notify: PPI Guid: 605EA650-C65C-42E1-BA80-91A52AB618C6, Peim notify entry point: 7AD7447B +Notify: PPI Guid: 605EA650-C65C-42E1-BA80-91A52AB618C6, Peim notify entry point: 7AD6E906 +Memory TOLM: A8000000 +PCIE OSBASE: E0000000 +PCIE BASE: E0000000 Size : 4000000 +PCI32 BASE: A8000000 Limit: DFFFFFFF +PCI64 BASE: F00000000 Limit: FFFFFFFFF +UC START: F00000000 End : 1000000000 +HandOffToDxeCore() Stack Base: 0x7A339000, Stack Size: 0x20000 +CoreInitializeMemoryServices: + BaseAddress - 0x71025000 Length - 0x8FDA000 MinimalMemorySizeNeeded - 0x310000 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7A379E08 +ProtectUefiImageCommon - 0x7A379E08 + - 0x000000007A359000 - 0x0000000000025000 +DxeMain: MemoryBaseAddress=0x71025000 MemoryLength=0x8FDA000 +HOBLIST address in DXE = 0x79CF6018 +Memory Allocation 0x00000004 0x7A339000 - 0x7A358FFF +Memory Allocation 0x00000003 0x7AFFF000 - 0x7AFFFFFF +Memory Allocation 0x00000003 0x7AFF7000 - 0x7AFFEFFF +Memory Allocation 0x00000004 0x7AD77000 - 0x7AFF6FFF +Memory Allocation 0x00000003 0x7AD74000 - 0x7AD76FFF +Memory Allocation 0x00000003 0x7AD6D000 - 0x7AD73FFF +Memory Allocation 0x00000003 0x7AD6B000 - 0x7AD6CFFF +Memory Allocation 0x00000003 0x7AD65000 - 0x7AD6AFFF +Memory Allocation 0x00000003 0x7AD62000 - 0x7AD64FFF +Memory Allocation 0x00000003 0x7AD60000 - 0x7AD61FFF +Memory Allocation 0x00000003 0x7AD5E000 - 0x7AD5FFFF +Memory Allocation 0x00000003 0x7AD5B000 - 0x7AD5DFFF +Memory Allocation 0x00000003 0x7AD59000 - 0x7AD5AFFF +Memory Allocation 0x00000003 0x7AD54000 - 0x7AD58FFF +Memory Allocation 0x00000004 0x7AD44000 - 0x7AD53FFF +Memory Allocation 0x00000004 0x7A387000 - 0x7AD43FFF +Memory Allocation 0x00000003 0x7A385000 - 0x7A386FFF +Memory Allocation 0x00000002 0x7A384000 - 0x7A384FFF +Memory Allocation 0x00000003 0x7A381000 - 0x7A383FFF +Memory Allocation 0x00000003 0x7A37E000 - 0x7A380FFF +Memory Allocation 0x00000003 0x7A359000 - 0x7A37DFFF +Memory Allocation 0x00000003 0x7A359000 - 0x7A37DFFF +Memory Allocation 0x00000004 0x7A339000 - 0x7A358FFF +Memory Allocation 0x00000004 0x7A000000 - 0x7A1FFFFF +Memory Allocation 0x00000007 0x7A200000 - 0x7A338FFF +Memory Allocation 0x00000004 0x71000000 - 0x7101FFFF +Memory Allocation 0x00000004 0x79FFF000 - 0x79FFFFFF +FV Hob 0x7A387010 - 0x7AD4300F +FV2 Hob 0x7A387010 - 0x7AD4300F + 00000000-0000-0000-0000-000000000000 - 9E21FD93-9C72-4C15-8C4B-E77F1DB2D792 +FV3 Hob 0x7A387010 - 0x7AD4300F - 0x0 - 0x1 + 00000000-0000-0000-0000-000000000000 - 9E21FD93-9C72-4C15-8C4B-E77F1DB2D792 +InstallProtocolInterface: D8117CFE-94A6-11D4-9A3A-0090273FC14D 7A3794D0 +InstallProtocolInterface: 8F644FA9-E850-4DB1-9CE2-0B44698E8DA4 79CF3230 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 79CF3598 +InstallProtocolInterface: 220E73B6-6BDB-4413-8405-B974B108619A 79CE8C30 +InstallProtocolInterface: EE4E5898-3914-4259-9D6E-DC7BD79403CF 7A37A160 +InstallProtocolInterface: FC1BCDB0-7D31-49AA-936A-A4600D9DD083 7A37A160 +InstallProtocolInterface: A31280AD-481E-41B6-95E8-127F4C984779 7A37A160 +Loading driver 80CF7257-87AB-47F9-A3FE-D50B76D89541 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79578C40 +Loading driver at 0x0007956A000 EntryPoint=0x0007956A3B4 PcdDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79578A98 +ProtectUefiImageCommon - 0x79578C40 + - 0x000000007956A000 - 0x0000000000006A60 +InstallProtocolInterface: 11B34006-D85B-4D0A-A290-D5A571310EF7 795701F0 +InstallProtocolInterface: 13A3F0F6-264A-3EF0-F2E0-DEC512342F34 79570150 +InstallProtocolInterface: 5BE40F57-FA68-4610-BBBF-E9C5FCDAD365 79570300 +InstallProtocolInterface: FD0F4478-0EFD-461D-BA2D-E58C45FD5F5E 795701E0 +Loading driver D93CE3D8-A7EB-4730-8C8E-CC466A9ECC3C +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79577340 +Loading driver at 0x00079EF4000 EntryPoint=0x00079EF5124 ReportStatusCodeRouterRuntimeDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79577918 +ProtectUefiImageCommon - 0x79577340 + - 0x0000000079EF4000 - 0x000000000000A000 +InstallProtocolInterface: 86212936-0E76-41C8-A03A-2AF2FC1C39E2 79EFA068 +InstallProtocolInterface: D2B2B828-0826-48A7-B3DF-983C006024F0 79EFA060 +Loading driver 6C2004EF-4E0E-4BE4-B14C-340EB4AA5891 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79576140 +Loading driver at 0x00079EED000 EntryPoint=0x00079EEE0F4 StatusCodeHandlerRuntimeDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79576C98 +ProtectUefiImageCommon - 0x79576140 + - 0x0000000079EED000 - 0x0000000000007000 +Loading driver CDE00010-3ACF-44D4-8CB0-346038232B97 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79576640 +ConvertPages: failed to find range 180000000 - 180005FFF +Loading driver at 0x0007955E000 EntryPoint=0x0007955E29C +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79573F18 +ProtectUefiImageCommon - 0x79576640 + - 0x000000007955E000 - 0x0000000000005BC0 +InstallProtocolInterface: CDE00002-E988-4697-8F36-08F13D8D3D39 79563430 +Loading driver 00160F8D-2B35-4DF2-BBE0-B272A8D631F0 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 795730C0 +Loading driver at 0x00079559000 EntryPoint=0x00079559374 FirmwarePerformanceDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79573B98 +ProtectUefiImageCommon - 0x795730C0 + - 0x0000000079559000 - 0x0000000000004720 +FPDT: WARNING: SEC Performance Data Hob not found, ResetEnd will be set to 0! +Loading driver A19B1FE7-C1BC-49F8-875F-54A5D542443F +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79572B40 +Loading driver at 0x00079564000 EntryPoint=0x00079564404 CpuIo2Dxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79573318 +ProtectUefiImageCommon - 0x79572B40 + - 0x0000000079564000 - 0x0000000000002F80 +InstallProtocolInterface: AD61F191-AE5F-4C0E-B9FA-E869D288C64F 79566CF8 +Loading driver F80697E9-7FD6-4665-8646-88E33EF71DFC +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79572240 +Loading driver at 0x00079449000 EntryPoint=0x000794494A4 SecurityStubDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79572498 +ProtectUefiImageCommon - 0x79572240 + - 0x0000000079449000 - 0x00000000000870C0 +InstallProtocolInterface: 94AB2F58-1438-4EF1-9152-18941A3A0E68 794C7258 +InstallProtocolInterface: A46423E3-4617-49F1-B9FF-D1BFA9115839 794C7250 +InstallProtocolInterface: 15853D7C-3DDF-43E0-A1CB-EBF85B8F872C 794C7260 +Loading driver 1A1E4886-9517-440E-9FDE-3BE44CEE2136 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 795712C0 +Loading driver at 0x00079535000 EntryPoint=0x00079536144 CpuDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79571A18 +ProtectUefiImageCommon - 0x795712C0 + - 0x0000000079535000 - 0x0000000000011140 +Paging: added 512 pages to page table pool +CurrentPagingContext: + MachineType - 0x8664 + PageTableBase - 0x7A001000 + Attributes - 0xC0000002 +InstallProtocolInterface: 26BACCB1-6F42-11D4-BCE7-0080C73C8881 79545170 +MemoryProtectionCpuArchProtocolNotify: +ProtectUefiImageCommon - 0x7A379E08 + - 0x000000007A359000 - 0x0000000000025000 +ProtectUefiImageCommon - 0x79578C40 + - 0x000000007956A000 - 0x0000000000006A60 +ProtectUefiImageCommon - 0x79577340 + - 0x0000000079EF4000 - 0x000000000000A000 +SetUefiImageMemoryAttributes - 0x0000000079EF4000 - 0x0000000000001000 (0x0000000000004000) +SetUefiImageMemoryAttributes - 0x0000000079EF5000 - 0x0000000000003000 (0x0000000000020000) +SetUefiImageMemoryAttributes - 0x0000000079EF8000 - 0x0000000000006000 (0x0000000000004000) +ProtectUefiImageCommon - 0x79576140 + - 0x0000000079EED000 - 0x0000000000007000 +SetUefiImageMemoryAttributes - 0x0000000079EED000 - 0x0000000000001000 (0x0000000000004000) +SetUefiImageMemoryAttributes - 0x0000000079EEE000 - 0x0000000000002000 (0x0000000000020000) +SetUefiImageMemoryAttributes - 0x0000000079EF0000 - 0x0000000000004000 (0x0000000000004000) +ProtectUefiImageCommon - 0x79576640 + - 0x000000007955E000 - 0x0000000000005BC0 +ProtectUefiImageCommon - 0x795730C0 + - 0x0000000079559000 - 0x0000000000004720 +ProtectUefiImageCommon - 0x79572B40 + - 0x0000000079564000 - 0x0000000000002F80 +ProtectUefiImageCommon - 0x79572240 + - 0x0000000079449000 - 0x00000000000870C0 +ProtectUefiImageCommon - 0x795712C0 + - 0x0000000079535000 - 0x0000000000011140 +ConvertPages: failed to find range A0000 - FFFFF +ConvertPages: failed to find range 7B000000 - 7B7FFFFF +ConvertPages: failed to find range 7BE00000 - 7BFFFFFF +ConvertPages: failed to find range 7C000000 - 7FFFFFFF +ConvertPages: failed to find range E0000000 - E3FFFFFF +ConvertPages: failed to find range FEC00000 - FEC00FFF +ConvertPages: failed to find range FED01000 - FED01FFF +ConvertPages: failed to find range FED03000 - FED03FFF +ConvertPages: failed to find range FED08000 - FED08FFF +ConvertPages: failed to find range FED0C000 - FED0FFFF +ConvertPages: failed to find range FED1C000 - FED1CFFF +ConvertPages: failed to find range FEE00000 - FEE00FFF +ConvertPages: failed to find range FEF00000 - FEFFFFFF +ConvertPages: failed to find range FF800000 - FFFFFFFF +AP Loop Mode is 1 +WakeupBufferStart = 87000, WakeupBufferSize = 38F +CpuDxe: 5-Level Paging = 0 +APIC MODE is 1 +MpInitLib: Find 4 processors in system. +GetMicrocodePatchInfoFromHob: Microcode patch cache HOB is not found. +ShadowMicrocodePatchByPcd: 0x1 microcode patches will be loaded into memory, with size 0xCC00. +ShadowMicrocodePatchWorker: Required microcode patches have been loaded at 0x79528000, with size 0xCC00. +CpuDxe: 5-Level Paging = 0 +CPU[0000]: Microcode revision = 00000909, expected = 00000909 +CPU[0001]: Microcode revision = 00000909, expected = 00000909 +CPU[0002]: Microcode revision = 00000909, expected = 00000909 +CPU[0003]: Microcode revision = 00000909, expected = 00000909 +Detect CPU count: 4 +Does not find any HOB stored CPU BIST information! +InstallProtocolInterface: 3FDDA605-A76E-4F46-AD29-12F4531B3D08 79545260 +Loading driver C8339973-A563-4561-B858-D8476F9DEFC4 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 795512C0 +Loading driver at 0x0007954A000 EntryPoint=0x0007954A3B4 Metronome.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79549018 +ProtectUefiImageCommon - 0x795512C0 + - 0x000000007954A000 - 0x00000000000027C0 +InstallProtocolInterface: 26BACCB2-6F42-11D4-BCE7-0080C73C8881 7954C5C0 +Loading driver B601F8C4-43B7-4784-95B1-F4226CB40CEE +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 795490C0 +Loading driver at 0x00079EE4000 EntryPoint=0x00079EE5154 RuntimeDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79549C98 +ProtectUefiImageCommon - 0x795490C0 + - 0x0000000079EE4000 - 0x0000000000009000 +SetUefiImageMemoryAttributes - 0x0000000079EE4000 - 0x0000000000001000 (0x0000000000004008) +SetUefiImageMemoryAttributes - 0x0000000079EE5000 - 0x0000000000002000 (0x0000000000020008) +SetUefiImageMemoryAttributes - 0x0000000079EE7000 - 0x0000000000006000 (0x0000000000004008) +InstallProtocolInterface: B7DFB4E1-052F-449F-87BE-9818FC91B733 79EE9070 +Loading driver 9B680FCE-AD6B-4F3A-B60B-F59899003443 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7954F040 +Loading driver at 0x0007950E000 EntryPoint=0x0007950E3B4 DevicePathDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 7954FF18 +ProtectUefiImageCommon - 0x7954F040 + - 0x000000007950E000 - 0x000000000000C7E0 +InstallProtocolInterface: 0379BE4E-D706-437D-B037-EDB82FB772A4 795161D0 +InstallProtocolInterface: 8B843E20-8132-4852-90CC-551A4E4A7F1C 795161C0 +InstallProtocolInterface: 05C99A21-C70F-4AD2-8A5F-35DF3343F51E 79516210 +Loading driver 96B5C032-DF4C-4B6E-8232-438DCF448D0E +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7954F4C0 +Loading driver at 0x00079522000 EntryPoint=0x000795223B4 NullMemoryTestDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 7954F818 +ProtectUefiImageCommon - 0x7954F4C0 + - 0x0000000079522000 - 0x0000000000002C00 +InstallProtocolInterface: 309DE7F1-7F5E-4ACE-B49C-531BE5AA95EF 795249A8 +Loading driver 14537DA0-222A-4BBE-9A5C-212A3CBCA9EF +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7954ECC0 +Loading driver at 0x000794F0000 EntryPoint=0x000794F0540 PchS3SupportDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 7954EB98 +ProtectUefiImageCommon - 0x7954ECC0 + - 0x00000000794F0000 - 0x000000000000E400 +InstallProtocolInterface: 14537DA0-222A-4BBE-9A5C-212A3CBCA9EF 0 + PDB = c:\work\mnw2\Build\Vlv2TbltDevicePkg\DEBUG_VS2015x86\X64\Vlv2DeviceRefCodePkg\ValleyView2Soc\SouthCluster\S3Support\Dxe\PchS3Support\DEBUG\PchS3SupportDxe.pdb +InstallProtocolInterface: E287D20B-D897-4E1E-A5D9-977763936A04 79FBCBB8 +Loading driver DD787473-07CE-4C63-82CE-930B33F39C09 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7954D040 +Loading driver at 0x00079ED9000 EntryPoint=0x00079EDA120 SmmControl.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 7954E598 +ProtectUefiImageCommon - 0x7954D040 + - 0x0000000079ED9000 - 0x000000000000B000 +SetUefiImageMemoryAttributes - 0x0000000079ED9000 - 0x0000000000001000 (0x0000000000004008) +SetUefiImageMemoryAttributes - 0x0000000079EDA000 - 0x0000000000005000 (0x0000000000020008) +SetUefiImageMemoryAttributes - 0x0000000079EDF000 - 0x0000000000005000 (0x0000000000004008) +SmmControlDriverEntryInit() Start +InstallProtocolInterface: 843DC720-AB1E-42CB-9357-8A0078F3561B 79EE0090 +SmmControlDriverEntryInit() End +Loading driver F5883FC5-F8EE-4E44-B386-6021FB320C9B +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7954D440 +Loading driver at 0x00079ECC000 EntryPoint=0x00079ECD150 PchReset.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 7954DA18 +ProtectUefiImageCommon - 0x7954D440 + - 0x0000000079ECC000 - 0x000000000000D000 +SetUefiImageMemoryAttributes - 0x0000000079ECC000 - 0x0000000000001000 (0x0000000000004008) +SetUefiImageMemoryAttributes - 0x0000000079ECD000 - 0x0000000000006000 (0x0000000000020008) +SetUefiImageMemoryAttributes - 0x0000000079ED3000 - 0x0000000000006000 (0x0000000000004008) +InitializePchReset() Start +InstallProtocolInterface: F0BBFCA0-684E-48B3-BAE2-6C84B89E5339 79DFBCA8 +InstallProtocolInterface: 27CFAC88-46CC-11D4-9A38-0090273FC14D 0 +InitializePchReset() End +Loading driver C194C6EA-B68C-4981-B64B-9BD271474B20 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 795481C0 +Loading driver at 0x00079EBB000 EntryPoint=0x00079EBC100 PchSpiRuntime.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79548118 +ProtectUefiImageCommon - 0x795481C0 + - 0x0000000079EBB000 - 0x0000000000011000 +SetUefiImageMemoryAttributes - 0x0000000079EBB000 - 0x0000000000001000 (0x0000000000004008) +SetUefiImageMemoryAttributes - 0x0000000079EBC000 - 0x000000000000A000 (0x0000000000020008) +SetUefiImageMemoryAttributes - 0x0000000079EC6000 - 0x0000000000006000 (0x0000000000004008) +InstallPchSpi() Start +InstallProtocolInterface: 1156EFC6-EA32-4396-B5D5-26932E83C313 79DFA028 +InstallPchSpi() End +Loading driver D6AC4AC2-8BC2-4CDD-8776-280E1469DE02 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79547B40 +Loading driver at 0x000794EA000 EntryPoint=0x000794EA3F0 PchPolicyInitDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79548498 +ProtectUefiImageCommon - 0x79547B40 + - 0x00000000794EA000 - 0x0000000000005C40 +InstallProtocolInterface: 4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5 794EF740 +Loading driver BDCE85BB-FBAA-4F4E-9264-501A2C249581 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79547140 +Loading driver at 0x000794E3000 EntryPoint=0x000794E33E4 S3SaveStateDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79547698 +ProtectUefiImageCommon - 0x79547140 + - 0x00000000794E3000 - 0x0000000000006F20 +InstallProtocolInterface: E857CAF6-C046-45DC-BE3F-EE0765FBA887 794E97D0 +Loading driver 9622E42C-8E38-4A08-9E8F-54F784652F6B +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79527C40 +Loading driver at 0x000794D1000 EntryPoint=0x000794D13D4 AcpiTableDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79527A98 +ProtectUefiImageCommon - 0x79527C40 + - 0x00000000794D1000 - 0x00000000000088E0 +InstallProtocolInterface: FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C 79527220 +InstallProtocolInterface: EB97088E-CFDF-49C6-BE4B-D906A5B20E86 79527230 +Loading driver 348C4D62-BFBD-4882-9ECE-C80BB1C4783B +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 795273C0 +Loading driver at 0x0007940B000 EntryPoint=0x0007940B3D4 HiiDatabase.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79526F98 +ProtectUefiImageCommon - 0x795273C0 + - 0x000000007940B000 - 0x000000000001E5A0 +InstallProtocolInterface: E9CA4775-8657-47FC-97E7-7ED65A084324 79427DB8 +InstallProtocolInterface: 0FD96974-23AA-4CDC-B9CB-98D17750322A 79427E30 +InstallProtocolInterface: EF9FC172-A1B2-4693-B327-6D32FC416042 79427E58 +InstallProtocolInterface: 587E72D7-CC50-4F79-8209-CA291FC1A10F 79427EB0 +InstallProtocolInterface: 0A8BADD5-03B8-4D19-B128-7B8F0EDAA596 79427EE0 +InstallProtocolInterface: 31A6406A-6BDF-4E46-B2A2-EBAA89C40920 79427DD8 +InstallProtocolInterface: 1A1241E6-8F19-41A9-BC0E-E8EF39E06546 79427E00 +Loading driver F9D88642-0737-49BC-81B5-6889CD57D9EA +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79525040 +Loading driver at 0x000794DD000 EntryPoint=0x000794DD3D4 SmbiosDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79526318 +ProtectUefiImageCommon - 0x79525040 + - 0x00000000794DD000 - 0x00000000000054C0 +InstallProtocolInterface: 03583FF6-CB36-4940-947E-B9B39F4AFAF7 794E2090 +Loading driver A210F973-229D-4F4D-AA37-9895E6C9EABA +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 795259C0 +Loading driver at 0x0007951C000 EntryPoint=0x0007951C3B4 DpcDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79525918 +ProtectUefiImageCommon - 0x795259C0 + - 0x000000007951C000 - 0x0000000000002D40 +InstallProtocolInterface: 480F8AE9-0C46-4AA9-BC89-DB9FBA619806 7951E8D8 +Loading driver FF626DA9-17EE-4949-A8B8-B10FA0044E9F +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79521040 +Loading driver at 0x00079441000 EntryPoint=0x00079441374 EsrtFmpDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79525498 +ProtectUefiImageCommon - 0x79521040 + - 0x0000000079441000 - 0x0000000000003D20 +Loading driver CDE000FF-AA41-42F1-9229-77490E939841 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79521AC0 +Loading driver at 0x00079446000 EntryPoint=0x000794465A8 cdeWelcomeDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79521898 +ProtectUefiImageCommon - 0x79521AC0 + - 0x0000000079446000 - 0x0000000000002EA0 + + +---------------- +cdeWelcomeDxe//a:\edk2-staging2021-12-19\CdePkg\CdeWelcome\main.c(78): INTRODUCTION: "CDETRACE" macro. -> + Parameters are typechecked at build time by compilers from GNU, MICROSOFT and others during 2015 to 2021 +Printing 256 bytes of initilaized memory in a "dump"-format: +0000: 00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F +0010: 10 11 12 13 14 15 16 17 - 18 19 1A 1B 1C 1D 1E 1F +0020: 20 21 22 23 24 25 26 27 - 28 29 2A 2B 2C 2D 2E 2F +0030: 30 31 32 33 34 35 36 37 - 38 39 3A 3B 3C 3D 3E 3F +0040: 40 41 42 43 44 45 46 47 - 48 49 4A 4B 4C 4D 4E 4F +0050: 50 51 52 53 54 55 56 57 - 58 59 5A 5B 5C 5D 5E 5F +0060: 60 61 62 63 64 65 66 67 - 68 69 6A 6B 6C 6D 6E 6F +0070: 70 71 72 73 74 75 76 77 - 78 79 7A 7B 7C 7D 7E 7F +0080: 80 81 82 83 84 85 86 87 - 88 89 8A 8B 8C 8D 8E 8F +0090: 90 91 92 93 94 95 96 97 - 98 99 9A 9B 9C 9D 9E 9F +00A0: A0 A1 A2 A3 A4 A5 A6 A7 - A8 A9 AA AB AC AD AE AF +00B0: B0 B1 B2 B3 B4 B5 B6 B7 - B8 B9 BA BB BC BD BE BF +00C0: C0 C1 C2 C3 C4 C5 C6 C7 - C8 C9 CA CB CC CD CE CF +00D0: D0 D1 D2 D3 D4 D5 D6 D7 - D8 D9 DA DB DC DD DE DF +00E0: E0 E1 E2 E3 E4 E5 E6 E7 - E8 E9 EA EB EC ED EE EF +00F0: F0 F1 F2 F3 F4 F5 F6 F7 - F8 F9 FA FB FC FD FE FF +3s... 2s... 1s... 0s... +Loading driver 4D2E57EE-0E3F-44DD-93C4-D3B57E96945D +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79520040 +Loading driver at 0x00079439000 EntryPoint=0x00079439438 CpuS3DataDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79521518 +ProtectUefiImageCommon - 0x79520040 + - 0x0000000079439000 - 0x0000000000003160 +Loading driver F74D20EE-37E7-48FC-97F7-9B1047749C69 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79520A40 +Loading driver at 0x0007942D000 EntryPoint=0x0007942D3D4 LogoDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79520398 +InstallProtocolInterface: 6A1EE763-D47A-43B4-AABE-EF1DE2AB56FC 7942F6E0 +ProtectUefiImageCommon - 0x79520A40 + - 0x000000007942D000 - 0x0000000000005600 +InstallProtocolInterface: 53CD299F-2BC1-40C0-8C07-23F64FDB30E0 7942F4E8 +Loading driver FE5CEA76-4F72-49E8-986F-2CD899DFFE5D +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7951B7C0 +Loading driver at 0x00078FF3000 EntryPoint=0x00078FF3394 FaultTolerantWriteDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 7951B718 +ProtectUefiImageCommon - 0x7951B7C0 + - 0x0000000078FF3000 - 0x0000000000006020 +Loading driver FD3B7E55-FA7B-4E07-AE1D-208B81FB0BAD +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 794DA040 +Loading driver at 0x00079EB0000 EntryPoint=0x00079EB1174 FvbRuntimeDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 794DAF18 +ProtectUefiImageCommon - 0x794DA040 + - 0x0000000079EB0000 - 0x000000000000B000 +SetUefiImageMemoryAttributes - 0x0000000079EB0000 - 0x0000000000001000 (0x0000000000004008) +SetUefiImageMemoryAttributes - 0x0000000079EB1000 - 0x0000000000003000 (0x0000000000020008) +SetUefiImageMemoryAttributes - 0x0000000079EB4000 - 0x0000000000007000 (0x0000000000004008) +OK - Found SPI Flash Type in SPI Flash Driver, Device Type ID 0 = 0x40! +Device Type ID 1 = 0x17! +SPI flash chip VID = 0xEF, DID0 = 0x40, DID1 = 0x17 +FwBlockService.c: Setting up DevicePath for 0xFFC40000: +FwBlockService.c: LocateDevicePath failed, install new interface 0xFFC40000: +InstallProtocolInterface: 8F644FA9-E850-4DB1-9CE2-0B44698E8DA4 79DFAEB0 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 79DFAF98 +FvbProtocolRead: Lba: 0x0 Offset: 0x0 NumBytes: 0x40, Buffer: 0x7A358B10 +FvbProtocolGetAttributes: This: 0x79DFAEB0 Attributes: 0x4FEFF +FvbProtocolGetBlockSize: Lba: 0x0 BlockSize: 0x7A358B00 NumOfBlocks: 0x7A358AF8 +Ftw: FtwWorkSpaceLba - 0x3, WorkBlockSize - 0x10000, FtwWorkSpaceBase - 0xE000 +Ftw: FtwSpareLba - 0x4, SpareBlockSize - 0x10000 +Ftw: NumberOfWorkBlock - 0x4, FtwWorkBlockLba - 0x0 +Ftw: WorkSpaceLbaInSpare - 0x3, WorkSpaceBaseInSpare - 0xE000 +FvbProtocolRead: Lba: 0x3 Offset: 0xE000 NumBytes: 0x2000, Buffer: 0x79436108 +Ftw: Remaining work space size - 1FE0 +InstallProtocolInterface: 3EBD9E82-2C78-4DE6-9786-8D4BFCB7C881 79436028 +FwBlockService.c: IMPI FirmwareVolBlockProt, DevPath 0xFFC40000: Success +Loading driver 6CE6B0DE-781C-4F6C-B42D-98346C614BEC +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 794DA3C0 +Loading driver at 0x00079401000 EntryPoint=0x00079401420 HpetTimerDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 794DA998 +ProtectUefiImageCommon - 0x794DA3C0 + - 0x0000000079401000 - 0x0000000000004020 +Init HPET Timer Driver +HPET Base Address = 0xFED00000 + HPET_GENERAL_CAPABILITIES_ID = 0x0429B17F8086A201 + HPET_GENERAL_CONFIGURATION = 0x0000000000000000 + HPET_GENERAL_INTERRUPT_STATUS = 0x0000000000000000 + HPET_MAIN_COUNTER = 0x000000000A77BA8D + HPET Main Counter Period = 69841279 (fs) + HPET_TIMER0_CONFIGURATION = 0x00F0000000000030 + HPET_TIMER0_COMPARATOR = 0x0000000000000000 + HPET_TIMER0_MSI_ROUTE = 0x0000000000000000 + HPET_TIMER1_CONFIGURATION = 0x00F0000000000000 + HPET_TIMER1_COMPARATOR = 0x00000000FFFFFFFF + HPET_TIMER1_MSI_ROUTE = 0x0000000000000000 + HPET_TIMER2_CONFIGURATION = 0x00F0080000000000 + HPET_TIMER2_COMPARATOR = 0x00000000FFFFFFFF + HPET_TIMER2_MSI_ROUTE = 0x0000000000000000 +Choose 64-bit HPET timer. +HPET Interrupt Mode I/O APIC +HPET I/O APIC IRQ = 0x14 +HPET Interrupt Vector = 0x40 +HPET Counter Mask = 0xFFFFFFFFFFFFFFFF +HPET Timer Period = 100000 +HPET Timer Count = 0x0000000000022F4D +HPET_TIMER0_CONFIGURATION = 0x00F0000000002836 +HPET_TIMER0_COMPARATOR = 0x000000000A7E4875 +HPET_TIMER0_MSI_ROUTE = 0x0000000000000000 +InstallProtocolInterface: 26BACCB3-6F42-11D4-BCE7-0080C73C8881 79404CD0 +Loading driver 99796403-CF03-42EC-A817-7183411D79E2 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79445CC0 +Loading driver at 0x00078FE1000 EntryPoint=0x00078FE13F0 PchSmbusDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79445A98 +ProtectUefiImageCommon - 0x79445CC0 + - 0x0000000078FE1000 - 0x0000000000008A00 +InitializePchSmbus() Start +InstallProtocolInterface: E49D33ED-513D-4634-B698-6F55AA751C1B 7943D048 +InitializePchSmbus() End +Loading driver 9FD2360E-6B48-11D5-8E71-00902707B35E +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 794452C0 +Loading driver at 0x00078FC7000 EntryPoint=0x00078FC73F0 PciHostBridge.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79445598 +ProtectUefiImageCommon - 0x794452C0 + - 0x0000000078FC7000 - 0x000000000000C2C0 +InstallProtocolInterface: CF8034BE-6768-4D8B-B739-7CCE683A9FBE 79435CC8 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78FD27D0 +InstallProtocolInterface: 2F707EBB-4A1A-11D4-9A38-0090273FC14D 79435220 + Allocating PCI space from 0x80000000 to 0xDFFFFFFF +Loading driver 2EE72E7C-FB9E-4318-B888-33A315C7A91D +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 794353C0 +Loading driver at 0x00079408000 EntryPoint=0x000794083A4 PpmPolicy.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79435718 +ProtectUefiImageCommon - 0x794353C0 + - 0x0000000079408000 - 0x0000000000002640 +InstallProtocolInterface: DDABFEAC-EF63-452C-8F39-ED7FAED8265E 7940A4A0 +Loading driver EBF342FE-B1D3-4EF8-957C-8048606FF671 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79434CC0 +Loading driver at 0x00078F95000 EntryPoint=0x00078F953D4 SetupBrowser.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79434B98 +ProtectUefiImageCommon - 0x79434CC0 + - 0x0000000078F95000 - 0x00000000000188E0 +InstallProtocolInterface: B9D4C360-BCFB-4F9B-9298-53C136982258 78FAC4D0 +InstallProtocolInterface: A770C357-B693-4E6D-A6CF-D21C728E550B 78FAC500 +InstallProtocolInterface: 1F73B18D-4630-43C1-A1DE-6F80855D7DA4 78FAC4E0 +Loading driver F099D67F-71AE-4C36-B2A3-DCEB0EB2B7D8 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7942CBC0 +Loading driver at 0x00078FED000 EntryPoint=0x00078FED3B4 WatchdogTimer.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 7942CE98 +ProtectUefiImageCommon - 0x7942CBC0 + - 0x0000000078FED000 - 0x0000000000002820 +InstallProtocolInterface: 665E3FF5-46CC-11D4-9A38-0090273FC14D 78FEF638 +Loading driver C1A69A12-8653-4FDE-A215-48FCD95288C3 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7942C240 +Loading driver at 0x00078F82000 EntryPoint=0x00078F82460 PlatformSetupDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 7942C598 +ProtectUefiImageCommon - 0x7942C240 + - 0x0000000078F82000 - 0x00000000000124A0 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78F91BC8 +InstallProtocolInterface: 330D4706-F2A0-4E4F-A369-B66FA8D54385 7942B8F8 +Loading driver 326E9CC6-9839-4885-B2ED-275903B668E1 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 79400AC0 +Loading driver at 0x00078FB9000 EntryPoint=0x00078FB93F0 SmmAccess.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 79400D98 +ProtectUefiImageCommon - 0x79400AC0 + - 0x0000000078FB9000 - 0x0000000000006400 +InstallProtocolInterface: C2702B74-800C-4131-8746-8FB5B89CE4AC 78FBEE70 +Loading driver E660EA85-058E-4B55-A54B-F02F83A24707 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78FF2CC0 +Loading driver at 0x00078F58000 EntryPoint=0x00078F58418 DisplayEngine.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78FF2B98 +ProtectUefiImageCommon - 0x78FF2CC0 + - 0x0000000078F58000 - 0x0000000000014A80 +InstallProtocolInterface: 9BBE29E9-FDA1-41EC-AD52-452213742D2E 78F6B3C8 +InstallProtocolInterface: 4311EDC0-6054-46D4-9E40-893EA952FCCC 78F6B3E0 +Loading driver 2FA2A6DA-11D5-4DC3-999A-749648B03C56 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78FEB1C0 +Loading driver at 0x00079EA4000 EntryPoint=0x00079EA5154 PiSmmIpl.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78FF2218 +ProtectUefiImageCommon - 0x78FEB1C0 + - 0x0000000079EA4000 - 0x000000000000C000 +SetUefiImageMemoryAttributes - 0x0000000079EA4000 - 0x0000000000001000 (0x0000000000004008) +SetUefiImageMemoryAttributes - 0x0000000079EA5000 - 0x0000000000005000 (0x0000000000020008) +SetUefiImageMemoryAttributes - 0x0000000079EAA000 - 0x0000000000006000 (0x0000000000004008) +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SMM IPL opened SMRAM window +SMM IPL found SMRAM window 7B001000 - 7B7FFFFF +SMRAM attributes: 0000000000000008 +SMM IPL loading SMM Core at SMRAM address 7B7EB000 +SMM IPL calling SMM Core at SMRAM address 7B7EC174 +PiSmmCoreImageBase - 0x000000007B7EB000 +PiSmmCoreImageSize - 0x0000000000014000 +SmmAddMemoryRegion + MemBase - 0x7B001000 + MemLength - 0x7EA000 + Type - 0x7 + Attributes - 0x2 +SmmAddMemoryRegion + MemBase - 0x7B000000 + MemLength - 0x1000 + Type - 0x6 + Attributes - 0x10 +SmmAddMemoryRegion + MemBase - 0x7B7EB000 + MemLength - 0x15000 + Type - 0x6 + Attributes - 0x12 +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +mSmmMemLibInternalMaximumSupportAddress = 0xFFFFFFFFF +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78FD7898 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E90C0 +InstallProtocolInterface: F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191 79EAC3D0 +InstallProtocolInterface: C68ED8E2-9DC6-4CBD-9D94-DB65ACC5C332 79EAC1A8 +InstallProtocolInterface: 378DAEDC-F06B-4446-8314-40AB933C87A3 79EAC1B0 +Evaluate SMM DEPEX for FFS(044310AB-77FD-402A-AF1A-87D4120E7329) + PUSH GUID(2FF29FA7-5E80-4ED9-B380-017D3C554FF4) = FALSE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(A6885402-D022-4B0E-A509-4711B90F2A39) + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(23A089B3-EED5-4AC5-B2AB-43E3298C2343) + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(A4EC8ADB-B7A8-47D1-8E52-EC820D0ACF6F) + PUSH GUID(D9072C35-EB8F-43AD-A220-34D40E2A8285) = FALSE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(470CB248-E8AC-473C-BB4F-81069A1FE6FD) + PUSH GUID(D326D041-BD31-4C01-B5A8-628BE87F0653) = FALSE + PUSH GUID(B7DFB4E1-052F-449F-87BE-9818FC91B733) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(27F4917B-A707-4AAD-9676-26DF168CBF0D) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC) + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(1A819E49-D8EE-48CB-9A9C-0AA0D2810A38) = FALSE + PUSH GUID(E287D20B-D897-4E1E-A5D9-977763936A04) = TRUE + PUSH GUID(843DC720-AB1E-42CB-9357-8A0078F3561B) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(6BE18C9C-BF61-499E-88EC-5CD57430460C) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(2F707EBB-4A1A-11D4-9A38-0090273FC14D) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(ACAEAA7A-C039-4424-88DA-F42212EA0E55) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(3920405B-C897-44DA-88F3-4C498A6FF736) = FALSE + PUSH GUID(D31F0400-7D16-4316-BF88-6065883B402B) = FALSE + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(B8B8B609-0B6C-4B8C-A731-DE03A6C3F3DC) + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C50B323E-9075-4F2A-AC8E-D2596A1085CC) = FALSE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = FALSE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(99C20A37-042A-46E2-80F4-E4027FDBC86F) + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(1B1183FA-1823-46A7-8872-9C578755409D) = FALSE + PUSH GUID(456D2859-A84B-4E47-A2EE-3276D886997D) = FALSE + PUSH GUID(C50B323E-9075-4F2A-AC8E-D2596A1085CC) = FALSE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = FALSE + PUSH GUID(1E5668E2-8481-11D4-BCF1-0080C73C8881) = FALSE + PUSH GUID(6441F818-6362-4E44-B570-7DBA31DD2453) = FALSE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(A3FF0EF5-0C28-42F5-B544-8C7DE1E80014) + PUSH GUID(3FDDA605-A76E-4F46-AD29-12F4531B3D08) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(A47EE2D8-F60E-42FD-8E58-7BD65EE4C29B) + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(33FB3535-F15E-4C17-B303-5EB94595ECB6) + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(E21F35A8-42FF-4050-82D6-93F7CDFA7073) + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = FALSE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(41E89AB0-BD3D-44B6-A431-E4836EFBF2CB) + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = FALSE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(DDABFEAC-EF63-452C-8F39-ED7FAED8265E) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(5122FA7B-17A3-4A8B-89AE-A93ADE92EADF) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = FALSE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(3FDDA605-A76E-4F46-AD29-12F4531B3D08) = TRUE + PUSH GUID(456D2859-A84B-4E47-A2EE-3276D886997D) = FALSE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(99EC6206-AA45-4CAE-B630-866755241C8A) + PUSH GUID(5BAB88BA-E0E2-4674-B6AD-B812F6881CD6) = FALSE + PUSH GUID(2F707EBB-4A1A-11D4-9A38-0090273FC14D) = TRUE + PUSH GUID(AD61F191-AE5F-4C0E-B9FA-E869D288C64F) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(220E73B6-6BDB-4413-8405-B974B108619A) = TRUE + PUSH GUID(EF9FC172-A1B2-4693-B327-6D32FC416042) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78FD6A98 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E8AC0 +Loading SMM driver at 0x0007B7DA000 EntryPoint=0x0007B7DB2A4 ReportStatusCodeRouterSmm.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SmmInstallProtocolInterface: 2FF29FA7-5E80-4ED9-B380-017D3C554FF4 7B7DF060 +SmmInstallProtocolInterface: 6AFD2B77-98C1-4ACD-A6F9-8A9439DE0FB1 7B7DF080 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78FD6198 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E88C0 +Loading SMM driver at 0x0007B743000 EntryPoint=0x0007B744374 VariableSmm.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +mSmmMemLibInternalMaximumSupportAddress = 0xFFFFFFFFF +VarCheckLibRegisterSetVariableCheckHandler - 0x7B74FE28 Success +VarCheckLibRegisterSetVariableCheckHandler - 0x7B74C334 Success +Variable driver common space: 0x3D79C 0x3D79C 0x3D79C +Variable driver will work with auth variable format! +SmmInstallProtocolInterface: ED32D533-99E6-4209-9CC0-2D72CDD998A7 7B7C8260 +SmmInstallProtocolInterface: B0D8F3C1-B7DE-4C11-BC89-2FB562C8C411 7B7C8248 +InstallProtocolInterface: ED32D533-99E6-4209-9CC0-2D72CDD998A7 0 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78FD6318 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E80C0 +Loading SMM driver at 0x0007B699000 EntryPoint=0x0007B69A240 PchSpiSmm.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Enter +SmmLockBoxSmmLib SmmLockBoxContext - 7B6A72B0 +SmmLockBoxSmmLib LockBoxDataAddress - 7B6A7020 +SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Exit +InstallProtocolInterface: D9072C35-EB8F-43AD-A220-34D40E2A8285 7B698F28 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78FD5E18 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E7AC0 +Loading SMM driver at 0x0007B686000 EntryPoint=0x0007B687240 PchSmiDispatcher.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +InstallProtocolInterface: E0744B81-9513-49CD-8CEA-E9245E7039DA 7B692168 +InstallProtocolInterface: C50B323E-9075-4F2A-AC8E-D2596A1085CC 7B692198 +InstallProtocolInterface: 3920405B-C897-44DA-88F3-4C498A6FF736 7B6921C8 +InstallProtocolInterface: 9CCA03FC-4C9E-4A19-9B06-ED7B479BDE55 7B692228 +InstallProtocolInterface: A05B6FFD-87AF-4E42-95C9-6228B63CF3F3 7B6920D8 +SmmInstallProtocolInterface: 456D2859-A84B-4E47-A2EE-3276D886997D 7B692108 +SmmInstallProtocolInterface: 18A3C6DC-5EEA-48C8-A1C1-B53389F98999 7B692138 +SmmInstallProtocolInterface: 1B1183FA-1823-46A7-8872-9C578755409D 7B6921F8 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78FD5598 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E70C0 +Loading SMM driver at 0x0007B66C000 EntryPoint=0x0007B66E184 PiSmmCpuDxeSmm.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SMRR Base: 0x7B000000, SMRR Size: 0x800000 +PcdCpuSmmCodeAccessCheckEnable = 1 +mAddressEncMask = 0x0 +PcdControlFlowEnforcementPropertyMask = 0 +SMRAM TileSize = 0x00002000 (0x00001000, 0x00001000) +SMRAM SaveState Buffer (0x7B65E000, 0x0000E000) +CPU[000] APIC ID=0000 SMBASE=7B656000 SaveState=7B665C00 Size=00000400 +CPU[001] APIC ID=0002 SMBASE=7B658000 SaveState=7B667C00 Size=00000400 +CPU[002] APIC ID=0004 SMBASE=7B65A000 SaveState=7B669C00 Size=00000400 +CPU[003] APIC ID=0006 SMBASE=7B65C000 SaveState=7B66BC00 Size=00000400 +Stacks - 0x7B646000 +mSmmStackSize - 0x6000 +PcdCpuSmmStackGuard - 0x1 +mXdSupported - 0x1 +One Semaphore Size = 0x40 +Total Semaphores Size = 0x540 +PhysicalAddressBits = 36, 5LPageTable = 0. +5LevelPaging Needed - 0 +1GPageTable Support - 0 +PcdCpuSmmRestrictedMemoryAccess - 1 +PhysicalAddressBits - 36 +Initialize IDT IST field for SMM Stack Guard +InstallProtocolInterface: 26EEB3DE-B689-492E-80F0-BE8BD7DA4BA7 7B680330 +SMM IPL registered SMM Entry Point address 7B7EC9A4 +SmmInstallProtocolInterface: EB346B97-975F-4A9F-8B22-F8E92BB3D569 7B680360 +SmmInstallProtocolInterface: 69B792EA-39CE-402D-A2A6-F721DE351DFE 7B680250 +CpuSmm: SpinLock Size = 0x40, PcdCpuSmmMpTokenCountPerChunk = 0x40 +SmmInstallProtocolInterface: 5D5450D7-990C-4180-A803-8E63F0608307 7B680400 +SmmInstallProtocolInterface: 1D202CAB-C8AB-4D5C-94F7-3CFCC0D3D335 7B6803D0 +SMM S3 SMRAM Structure = 79CF6BB8 +SMM S3 Structure = 7B000000 +SMM CPU Module exit from SMRAM with EFI_SUCCESS +SMM IPL closed SMRAM window +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78FD5318 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E6EC0 +Loading SMM driver at 0x0007B5E3000 EntryPoint=0x0007B5E4274 CpuIo2Smm.efi +SmmInstallProtocolInterface: 3242A9D8-CE70-4AA0-955D-5E7B140DE4D2 7B5E7028 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78FD4E18 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E6CC0 +Loading SMM driver at 0x0007B5D6000 EntryPoint=0x0007B5D72B4 SmmLockBox.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SmmLockBoxSmmLib SmmLockBoxMmConstructor - Enter +SmmLockBoxSmmLib SmmLockBoxContext - already installed +SmmLockBoxSmmLib SmmLockBoxMmConstructor - Exit +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +mSmmMemLibInternalMaximumSupportAddress = 0xFFFFFFFFF +InstallProtocolInterface: BD445D79-B7AD-4F04-9AD8-29BD2040EB3C 0 +Evaluate SMM DEPEX for FFS(044310AB-77FD-402A-AF1A-87D4120E7329) + PUSH GUID(2FF29FA7-5E80-4ED9-B380-017D3C554FF4) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(A4EC8ADB-B7A8-47D1-8E52-EC820D0ACF6F) + PUSH GUID(D9072C35-EB8F-43AD-A220-34D40E2A8285) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(470CB248-E8AC-473C-BB4F-81069A1FE6FD) + PUSH GUID(D326D041-BD31-4C01-B5A8-628BE87F0653) = FALSE + PUSH GUID(B7DFB4E1-052F-449F-87BE-9818FC91B733) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC) + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(1A819E49-D8EE-48CB-9A9C-0AA0D2810A38) = FALSE + PUSH GUID(E287D20B-D897-4E1E-A5D9-977763936A04) = TRUE + PUSH GUID(843DC720-AB1E-42CB-9357-8A0078F3561B) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(ACAEAA7A-C039-4424-88DA-F42212EA0E55) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(3920405B-C897-44DA-88F3-4C498A6FF736) = TRUE + PUSH GUID(D31F0400-7D16-4316-BF88-6065883B402B) = FALSE + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(B8B8B609-0B6C-4B8C-A731-DE03A6C3F3DC) + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C50B323E-9075-4F2A-AC8E-D2596A1085CC) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + AND + AND + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(99C20A37-042A-46E2-80F4-E4027FDBC86F) + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(1B1183FA-1823-46A7-8872-9C578755409D) = TRUE + PUSH GUID(456D2859-A84B-4E47-A2EE-3276D886997D) = TRUE + PUSH GUID(C50B323E-9075-4F2A-AC8E-D2596A1085CC) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(1E5668E2-8481-11D4-BCF1-0080C73C8881) = FALSE + PUSH GUID(6441F818-6362-4E44-B570-7DBA31DD2453) = FALSE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(E21F35A8-42FF-4050-82D6-93F7CDFA7073) + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(41E89AB0-BD3D-44B6-A431-E4836EFBF2CB) + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(DDABFEAC-EF63-452C-8F39-ED7FAED8265E) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(5122FA7B-17A3-4A8B-89AE-A93ADE92EADF) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(3FDDA605-A76E-4F46-AD29-12F4531B3D08) = TRUE + PUSH GUID(456D2859-A84B-4E47-A2EE-3276D886997D) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(99EC6206-AA45-4CAE-B630-866755241C8A) + PUSH GUID(5BAB88BA-E0E2-4674-B6AD-B812F6881CD6) = FALSE + PUSH GUID(2F707EBB-4A1A-11D4-9A38-0090273FC14D) = TRUE + PUSH GUID(AD61F191-AE5F-4C0E-B9FA-E869D288C64F) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(220E73B6-6BDB-4413-8405-B974B108619A) = TRUE + PUSH GUID(EF9FC172-A1B2-4693-B327-6D32FC416042) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78FD4A18 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E8CC0 +Loading SMM driver at 0x0007B5CA000 EntryPoint=0x0007B5CB2A4 FirmwarePerformanceSmm.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SmmLockBoxSmmLib SmmLockBoxMmConstructor - Enter +SmmLockBoxSmmLib SmmLockBoxContext - already installed +SmmLockBoxSmmLib SmmLockBoxMmConstructor - Exit +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +mSmmMemLibInternalMaximumSupportAddress = 0xFFFFFFFFF +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78FD4118 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E84C0 +Loading SMM driver at 0x0007B5BD000 EntryPoint=0x0007B5BE2F4 FvbSmm.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +OK - Found SPI Flash Type in SPI Flash Driver, Device Type ID 0 = 0x40! +Device Type ID 1 = 0x17! +SPI flash chip VID = 0xEF, DID0 = 0x40, DID1 = 0x17 +SmmInstallProtocolInterface: D326D041-BD31-4C01-B5A8-628BE87F0653 7B5C9BB0 +SmmInstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 7B5C9B18 +InstallProtocolInterface: D326D041-BD31-4C01-B5A8-628BE87F0653 7B5C9BB0 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78FD4298 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E76C0 +Loading SMM driver at 0x0007B5B0000 EntryPoint=0x0007B5B1230 PchBiosWriteProtect.efi +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78F6D018 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E6AC0 +Loading SMM driver at 0x0007B5A6000 EntryPoint=0x0007B5A72A4 PiSmmCommunicationSmm.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +mSmmMemLibInternalMaximumSupportAddress = 0xFFFFFFFFF +SmmCommunication SwSmi: FFFFFFFF +SmmCommunication BufferPtrAddress: 0x0000000079F8D000, BufferPtr: 0x0000000000000000 +Evaluate SMM DEPEX for FFS(470CB248-E8AC-473C-BB4F-81069A1FE6FD) + PUSH GUID(D326D041-BD31-4C01-B5A8-628BE87F0653) = TRUE + PUSH GUID(B7DFB4E1-052F-449F-87BE-9818FC91B733) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC) + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(1A819E49-D8EE-48CB-9A9C-0AA0D2810A38) = FALSE + PUSH GUID(E287D20B-D897-4E1E-A5D9-977763936A04) = TRUE + PUSH GUID(843DC720-AB1E-42CB-9357-8A0078F3561B) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(ACAEAA7A-C039-4424-88DA-F42212EA0E55) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(3920405B-C897-44DA-88F3-4C498A6FF736) = TRUE + PUSH GUID(D31F0400-7D16-4316-BF88-6065883B402B) = FALSE + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(99C20A37-042A-46E2-80F4-E4027FDBC86F) + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(1B1183FA-1823-46A7-8872-9C578755409D) = TRUE + PUSH GUID(456D2859-A84B-4E47-A2EE-3276D886997D) = TRUE + PUSH GUID(C50B323E-9075-4F2A-AC8E-D2596A1085CC) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(1E5668E2-8481-11D4-BCF1-0080C73C8881) = FALSE + PUSH GUID(6441F818-6362-4E44-B570-7DBA31DD2453) = FALSE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(41E89AB0-BD3D-44B6-A431-E4836EFBF2CB) + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(DDABFEAC-EF63-452C-8F39-ED7FAED8265E) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(5122FA7B-17A3-4A8B-89AE-A93ADE92EADF) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(3FDDA605-A76E-4F46-AD29-12F4531B3D08) = TRUE + PUSH GUID(456D2859-A84B-4E47-A2EE-3276D886997D) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(99EC6206-AA45-4CAE-B630-866755241C8A) + PUSH GUID(5BAB88BA-E0E2-4674-B6AD-B812F6881CD6) = FALSE + PUSH GUID(2F707EBB-4A1A-11D4-9A38-0090273FC14D) = TRUE + PUSH GUID(AD61F191-AE5F-4C0E-B9FA-E869D288C64F) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(220E73B6-6BDB-4413-8405-B974B108619A) = TRUE + PUSH GUID(EF9FC172-A1B2-4693-B327-6D32FC416042) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78F6DC98 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E82C0 +Loading SMM driver at 0x0007B598000 EntryPoint=0x0007B5992D4 SmmFaultTolerantWriteDxe.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +mSmmMemLibInternalMaximumSupportAddress = 0xFFFFFFFFF +FvbProtocolGetAttributes: This: 0x7B5C9BB0 Attributes: 0x4FEFF +FvbProtocolGetBlockSize: Lba: 0x0 BlockSize: 0x7B64B820 NumOfBlocks: 0x7B64B818 +Ftw: FtwWorkSpaceLba - 0x3, WorkBlockSize - 0x10000, FtwWorkSpaceBase - 0xE000 +Ftw: FtwSpareLba - 0x4, SpareBlockSize - 0x10000 +Ftw: NumberOfWorkBlock - 0x4, FtwWorkBlockLba - 0x0 +Ftw: WorkSpaceLbaInSpare - 0x3, WorkSpaceBaseInSpare - 0xE000 +FvbProtocolRead: Lba: 0x3 Offset: 0xE000 NumBytes: 0x2000, Buffer: 0x7B595108 +Ftw: Remaining work space size - 1FE0 +SmmInstallProtocolInterface: 3868FC3B-7E45-43A7-906C-4BA47DE1754D 7B595028 +FvbProtocolGetAttributes: This: 0x7B5C9BB0 Attributes: 0x4FEFF +FvbProtocolGetBlockSize: Lba: 0x0 BlockSize: 0x7B64B798 NumOfBlocks: 0x7B64B7A0 +FvbProtocolWrite: Lba: 0x0 Offset: 0x64 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x66 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0xA0 NumBytes: 0x22, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x66 NumBytes: 0x1, Buffer: 0x7B6DF01A +Variable driver flush the HOB variable to flash: 8BE4DF61-93CA-11D2-AA0D-00E098032B8C HwErrRecSupport Success +Variable driver set the HOB variable to DELETED state in local: 8BE4DF61-93CA-11D2-AA0D-00E098032B8C HwErrRecSupport +FvbProtocolWrite: Lba: 0x0 Offset: 0xC4 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0xC6 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x100 NumBytes: 0x12, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0xC6 NumBytes: 0x1, Buffer: 0x7B6DF01A +Variable driver flush the HOB variable to flash: 8BE4DF61-93CA-11D2-AA0D-00E098032B8C Timeout Success +Variable driver set the HOB variable to DELETED state in local: 8BE4DF61-93CA-11D2-AA0D-00E098032B8C Timeout +FvbProtocolWrite: Lba: 0x0 Offset: 0x114 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x116 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x150 NumBytes: 0x15, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x116 NumBytes: 0x1, Buffer: 0x7B6DF01A +Variable driver flush the HOB variable to flash: 69D13BF0-AF91-4D96-AA9F-2184C5CE3BC0 BootState Success +Variable driver set the HOB variable to DELETED state in local: 69D13BF0-AF91-4D96-AA9F-2184C5CE3BC0 BootState +FvbProtocolWrite: Lba: 0x0 Offset: 0x168 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x16A NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x1A4 NumBytes: 0x3A9, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x16A NumBytes: 0x1, Buffer: 0x7B6DF01A +Variable driver flush the HOB variable to flash: EC87D643-EBA4-4BB5-A1E5-3F3E36B20DA9 Setup Success +Variable driver set the HOB variable to DELETED state in local: EC87D643-EBA4-4BB5-A1E5-3F3E36B20DA9 Setup +Variable driver: all HOB variables have been flushed in flash. +Variable PK does not exist. +Variable SetupMode is 1 +Variable SecureBoot is 0 +Variable SecureBootEnable is 0 +FvbProtocolWrite: Lba: 0x0 Offset: 0x550 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x552 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x58C NumBytes: 0x17, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x552 NumBytes: 0x1, Buffer: 0x7B6DF01A +Variable CustomMode is 0 +FvbProtocolWrite: Lba: 0x0 Offset: 0x5A4 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x5A6 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x5E0 NumBytes: 0x12, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x5A6 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x5F4 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x5F6 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x630 NumBytes: 0x1B, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x5F6 NumBytes: 0x1, Buffer: 0x7B6DF01A +Variable VendorKeys is 1 +Variable driver will work with auth variable support! +InstallProtocolInterface: 93BA1826-DFFB-45DD-82A7-E7DCAA3BBDF3 0 +InstallProtocolInterface: 3868FC3B-7E45-43A7-906C-4BA47DE1754D 0 +Evaluate SMM DEPEX for FFS(D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC) + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(1A819E49-D8EE-48CB-9A9C-0AA0D2810A38) = FALSE + PUSH GUID(E287D20B-D897-4E1E-A5D9-977763936A04) = TRUE + PUSH GUID(843DC720-AB1E-42CB-9357-8A0078F3561B) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(ACAEAA7A-C039-4424-88DA-F42212EA0E55) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(3920405B-C897-44DA-88F3-4C498A6FF736) = TRUE + PUSH GUID(D31F0400-7D16-4316-BF88-6065883B402B) = FALSE + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(99C20A37-042A-46E2-80F4-E4027FDBC86F) + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(1B1183FA-1823-46A7-8872-9C578755409D) = TRUE + PUSH GUID(456D2859-A84B-4E47-A2EE-3276D886997D) = TRUE + PUSH GUID(C50B323E-9075-4F2A-AC8E-D2596A1085CC) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(1E5668E2-8481-11D4-BCF1-0080C73C8881) = FALSE + PUSH GUID(6441F818-6362-4E44-B570-7DBA31DD2453) = FALSE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(41E89AB0-BD3D-44B6-A431-E4836EFBF2CB) + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(DDABFEAC-EF63-452C-8F39-ED7FAED8265E) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(5122FA7B-17A3-4A8B-89AE-A93ADE92EADF) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(3FDDA605-A76E-4F46-AD29-12F4531B3D08) = TRUE + PUSH GUID(456D2859-A84B-4E47-A2EE-3276D886997D) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(99EC6206-AA45-4CAE-B630-866755241C8A) + PUSH GUID(5BAB88BA-E0E2-4674-B6AD-B812F6881CD6) = FALSE + PUSH GUID(2F707EBB-4A1A-11D4-9A38-0090273FC14D) = TRUE + PUSH GUID(AD61F191-AE5F-4C0E-B9FA-E869D288C64F) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(220E73B6-6BDB-4413-8405-B974B108619A) = TRUE + PUSH GUID(EF9FC172-A1B2-4693-B327-6D32FC416042) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Loading driver 9F7DCADE-11EA-448A-A46F-76E003657DD1 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78F6D1C0 +Loading driver at 0x00079E98000 EntryPoint=0x00079E99114 VariableSmmRuntimeDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78F6D518 +ProtectUefiImageCommon - 0x78F6D1C0 + - 0x0000000079E98000 - 0x000000000000C000 +SetUefiImageMemoryAttributes - 0x0000000079E98000 - 0x0000000000001000 (0x0000000000004008) +SetUefiImageMemoryAttributes - 0x0000000079E99000 - 0x0000000000005000 (0x0000000000020008) +SetUefiImageMemoryAttributes - 0x0000000079E9E000 - 0x0000000000006000 (0x0000000000004008) +Variable driver runtime cache is enabled. +InstallProtocolInterface: 1E5668E2-8481-11D4-BCF1-0080C73C8881 0 +InstallProtocolInterface: CD3D0A05-9E24-437C-A891-1EE053DB7638 79EA02D0 +InstallProtocolInterface: AF23B340-97B4-4685-8D4F-A3F28169B21D 79EA02A0 +FPDT: ACPI S3 Performance Table address = 0x79F75000 +SmmLockBoxDxeLib SaveLockBox - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A358BD8 +SmmLockBox Command - 1 +SmmLockBoxSmmLib SaveLockBox - Enter +LockBoxGuid - 0DC65ADC-A973-4130-8DF0-2ADBEB9E4A31, SmramBuffer - 0x7B571000, Length - 0x8 +SmmLockBoxSmmLib SaveLockBox - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SaveLockBox - Exit (Success) +InstallProtocolInterface: 6441F818-6362-4E44-B570-7DBA31DD2453 0 +InstallProtocolInterface: 81D1675C-86F6-48DF-BD95-9A6E4F0925C3 79EA0220 +Loading driver FA20568B-548B-4B2B-81EF-1BA08D4A3CEC +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E25240 +Loading driver at 0x00078E07000 EntryPoint=0x00078E07BF4 BootScriptExecutorDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E25B18 +ProtectUefiImageCommon - 0x78E25240 + - 0x0000000078E07000 - 0x000000000000E300 +Evaluate SMM DEPEX for FFS(D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC) + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(1A819E49-D8EE-48CB-9A9C-0AA0D2810A38) = FALSE + PUSH GUID(E287D20B-D897-4E1E-A5D9-977763936A04) = TRUE + PUSH GUID(843DC720-AB1E-42CB-9357-8A0078F3561B) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(ACAEAA7A-C039-4424-88DA-F42212EA0E55) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(3920405B-C897-44DA-88F3-4C498A6FF736) = TRUE + PUSH GUID(D31F0400-7D16-4316-BF88-6065883B402B) = FALSE + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(99C20A37-042A-46E2-80F4-E4027FDBC86F) + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(1B1183FA-1823-46A7-8872-9C578755409D) = TRUE + PUSH GUID(456D2859-A84B-4E47-A2EE-3276D886997D) = TRUE + PUSH GUID(C50B323E-9075-4F2A-AC8E-D2596A1085CC) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(1E5668E2-8481-11D4-BCF1-0080C73C8881) = TRUE + PUSH GUID(6441F818-6362-4E44-B570-7DBA31DD2453) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(41E89AB0-BD3D-44B6-A431-E4836EFBF2CB) + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(DDABFEAC-EF63-452C-8F39-ED7FAED8265E) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(5122FA7B-17A3-4A8B-89AE-A93ADE92EADF) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(3FDDA605-A76E-4F46-AD29-12F4531B3D08) = TRUE + PUSH GUID(456D2859-A84B-4E47-A2EE-3276D886997D) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(99EC6206-AA45-4CAE-B630-866755241C8A) + PUSH GUID(5BAB88BA-E0E2-4674-B6AD-B812F6881CD6) = FALSE + PUSH GUID(2F707EBB-4A1A-11D4-9A38-0090273FC14D) = TRUE + PUSH GUID(AD61F191-AE5F-4C0E-B9FA-E869D288C64F) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = FALSE + PUSH GUID(220E73B6-6BDB-4413-8405-B974B108619A) = TRUE + PUSH GUID(EF9FC172-A1B2-4693-B327-6D32FC416042) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Loading driver CDE00011-E3A6-4B9A-AD76-1C0F23938A10 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E2D0C0 +Loading driver at 0x00078E20000 EntryPoint=0x00078E203F8 CdeLoadOptionsDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E2DA98 +ProtectUefiImageCommon - 0x78E2D0C0 + - 0x0000000078E20000 - 0x0000000000004720 +InstallProtocolInterface: CDE00000-2C09-4284-90F9-9A988ABDF6FB 78E23DE0 +Loading driver 6D33944A-EC75-4855-A54D-809C75241F6C +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E2D4C0 +Loading driver at 0x00078DC9000 EntryPoint=0x00078DC9414 BdsDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E2D818 +ProtectUefiImageCommon - 0x78E2D4C0 + - 0x0000000078DC9000 - 0x000000000001E180 +InstallProtocolInterface: 665E3FF6-46CC-11D4-9A38-0090273FC14D 78DE5760 +Loading driver F0E6A44F-7195-41C3-AC64-54F202CD0A21 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E2C840 +Loading driver at 0x00078CDD000 EntryPoint=0x00078CDD58C SecureBootConfigDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E2C798 +ProtectUefiImageCommon - 0x78E2C840 + - 0x0000000078CDD000 - 0x00000000000751C0 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78E2C398 +InstallProtocolInterface: 330D4706-F2A0-4E4F-A369-B66FA8D54385 78D4A728 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78D49CA8 +InstallProtocolInterface: 330D4706-F2A0-4E4F-A369-B66FA8D54385 78E2A420 +InstallProtocolInterface: F0E6A44F-7195-41C3-AC64-54F202CD0A21 78E2A418 +Loading driver 42857F0A-13F2-4B21-8A23-53D3F714B840 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E1F340 +Loading driver at 0x00079E8C000 EntryPoint=0x00079E8D154 CapsuleRuntimeDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E1F898 +ProtectUefiImageCommon - 0x78E1F340 + - 0x0000000079E8C000 - 0x000000000000C000 +SetUefiImageMemoryAttributes - 0x0000000079E8C000 - 0x0000000000001000 (0x0000000000004008) +SetUefiImageMemoryAttributes - 0x0000000079E8D000 - 0x0000000000005000 (0x0000000000020008) +SetUefiImageMemoryAttributes - 0x0000000079E92000 - 0x0000000000006000 (0x0000000000004008) +CapsuleRuntimeDxe X64 TotalPagesNum - 0xE pages +FvbProtocolWrite: Lba: 0x0 Offset: 0x64C NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x64E NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x688 NumBytes: 0x44, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x64E NumBytes: 0x1, Buffer: 0x7B6DF01A +!!! DEPRECATED INTERFACE !!! VariableLockRequestToLock() will go away soon! +!!! DEPRECATED INTERFACE !!! Please move to use Variable Policy! +!!! DEPRECATED INTERFACE !!! Variable: 711C703F-C285-4B10-A3B0-36ECBD3C8BE2 CapsuleLongModeBuffer +InstallProtocolInterface: 5053697E-2CBC-4819-90D9-0580DEEE5754 0 +Loading driver AD608272-D07F-4964-801E-7BD3B7888652 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E29940 +Loading driver at 0x00079E85000 EntryPoint=0x00079E860F4 MonotonicCounterRuntimeDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E29818 +ProtectUefiImageCommon - 0x78E29940 + - 0x0000000079E85000 - 0x0000000000007000 +SetUefiImageMemoryAttributes - 0x0000000079E85000 - 0x0000000000001000 (0x0000000000004008) +SetUefiImageMemoryAttributes - 0x0000000079E86000 - 0x0000000000002000 (0x0000000000020008) +SetUefiImageMemoryAttributes - 0x0000000079E88000 - 0x0000000000004000 (0x0000000000004008) +FvbProtocolWrite: Lba: 0x0 Offset: 0x6CC NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x6CE NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x708 NumBytes: 0xC, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x6CE NumBytes: 0x1, Buffer: 0x7B6DF01A +InstallProtocolInterface: 1DA97072-BDDC-4B30-99F1-72A0B56FFF2A 0 +Loading driver 378D7B65-8DA9-4773-B6E4-A47826A833E1 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E28CC0 +Loading driver at 0x00079E7B000 EntryPoint=0x00079E7C0F4 PcRtc.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E28818 +ProtectUefiImageCommon - 0x78E28CC0 + - 0x0000000079E7B000 - 0x000000000000A000 +SetUefiImageMemoryAttributes - 0x0000000079E7B000 - 0x0000000000001000 (0x0000000000004008) +SetUefiImageMemoryAttributes - 0x0000000079E7C000 - 0x0000000000004000 (0x0000000000020008) +SetUefiImageMemoryAttributes - 0x0000000079E80000 - 0x0000000000005000 (0x0000000000004008) +InstallProtocolInterface: 27CFAC87-46CC-11D4-9A38-0090273FC14D 0 +Loading driver 025F738B-4EBD-4D55-B728-5F421B601F1F +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E1B040 +Loading driver at 0x00078E18000 EntryPoint=0x00078E18394 PlatformInfoDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E1BF18 +ProtectUefiImageCommon - 0x78E1B040 + - 0x0000000078E18000 - 0x0000000000002D60 +FvbProtocolWrite: Lba: 0x0 Offset: 0x714 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x716 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x750 NumBytes: 0x19, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x716 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x76C NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x76E NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x7A8 NumBytes: 0x11F, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x76E NumBytes: 0x1, Buffer: 0x7B6DF01A +Loading driver 025F738B-4EBD-4D55-B728-5F421B601F20 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E1BAC0 +Loading driver at 0x00078DFF000 EntryPoint=0x00078DFF3EC PlatformCpuInfoDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E1B898 +ProtectUefiImageCommon - 0x78E1BAC0 + - 0x0000000078DFF000 - 0x0000000000003FA0 +Loading driver E2441B64-7EF4-41FE-B3A3-8CAA7F8D3017 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E1E040 +Loading driver at 0x00078DFB000 EntryPoint=0x00078DFB3D4 PciPlatform.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E1B518 +ProtectUefiImageCommon - 0x78E1E040 + - 0x0000000078DFB000 - 0x0000000000003800 +InstallProtocolInterface: 07D75280-27D4-4D69-90D0-5643E238B341 78DFE088 +Loading driver E0ECBEC9-B193-4351-A488-36A655F22F9F +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E1E9C0 +Loading driver at 0x00078DF8000 EntryPoint=0x00078DF8394 SaveMemoryConfig.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E1E918 +ProtectUefiImageCommon - 0x78E1E9C0 + - 0x0000000078DF8000 - 0x0000000000002E80 +InstallProtocolInterface: 6F20F7C8-E5EF-4F21-8D19-EDC5F0C496AE 78E1E518 +FvbProtocolWrite: Lba: 0x0 Offset: 0x8C8 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x8CA NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x904 NumBytes: 0x167A, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x8CA NumBytes: 0x1, Buffer: 0x7B6DF01A +Loading driver CB933912-DF8F-4305-B1F9-7B44FA11395C +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E1D040 +Loading driver at 0x00078DC0000 EntryPoint=0x00078DC03F0 PlatformCpuPolicy.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E1DD18 +ProtectUefiImageCommon - 0x78E1D040 + - 0x0000000078DC0000 - 0x0000000000008A40 +InstallProtocolInterface: BD26CDC9-A092-462A-877A-5AB6ADCE4812 78DC7F70 +Loading driver 9737D7CA-D869-45E5-A5EF-75D9438688DE +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E1D440 +Loading driver at 0x00078DF5000 EntryPoint=0x00078DF5374 PlatformGOPPolicy.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E1DC18 +ProtectUefiImageCommon - 0x78E1D440 + - 0x0000000078DF5000 - 0x00000000000027E0 +InstallProtocolInterface: EC2E931B-3281-48A5-8107-DF8A8BED3C5D 78DF7660 +Loading driver CE7CD764-A1D9-44E5-9857-14FEFAAE96DD +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E1C040 +Loading driver at 0x00078DB7000 EntryPoint=0x00078DB73F0 PnpDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E1CF18 +ProtectUefiImageCommon - 0x78E1C040 + - 0x0000000078DB7000 - 0x0000000000008380 +Config PnpSetting Start !!! +Bx PNP Power & Performance table +PnpDxe Power & Performance +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[22:22], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[21:21], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[20:20], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[19:19], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[18:18], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[17:17], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[16:16], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[15:15], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[14:14], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[12:12], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[11:11], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[10:10], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[ 9: 9], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[ 8: 8], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[ 7: 7], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[ 6: 6], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[ 5: 5], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[ 4: 4], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[ 3: 3], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[ 2: 2], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[ 1: 1], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x18, Field[ 0: 0], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x20, Field[26:24], Value: 2. Result: 2 +Output PwrPerf Register: PortID: 0x0, Offset:0x20, Field[ 8: 0], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x21, Field[31:31], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x0, Offset:0x21, Field[ 8: 8], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x0, Offset:0xC0, Field[11: 8], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x0, Offset:0xC0, Field[ 7: 4], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x0, Offset:0xC0, Field[ 3: 0], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x3, Offset:0x3, Field[29:24], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x3, Offset:0x3, Field[21:16], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x3, Offset:0x3, Field[13: 8], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x3, Offset:0x3, Field[ 5: 0], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x3, Offset:0x4, Field[29:24], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x3, Offset:0x4, Field[21:16], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x3, Offset:0x4, Field[13: 8], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x3, Offset:0x4, Field[ 5: 0], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x3, Offset:0x5, Field[21:16], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x3, Offset:0x5, Field[13: 8], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x3, Offset:0x5, Field[ 5: 0], Value: 8. Result: 8 +Output PwrPerf Register: PortID: 0x3, Offset:0x7, Field[31:24], Value: 20. Result: 20 +Output PwrPerf Register: PortID: 0x3, Offset:0x7, Field[15: 8], Value: A. Result: A +Output PwrPerf Register: PortID: 0x3, Offset:0x7, Field[ 7: 0], Value: 10. Result: 10 +Output PwrPerf Register: PortID: 0x3, Offset:0x8, Field[23: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x9, Field[23: 0], Value: 3FFFFC. Result: 3FFFFC +Output PwrPerf Register: PortID: 0x3, Offset:0xA, Field[ 9: 0], Value: 80. Result: 80 +Output PwrPerf Register: PortID: 0x3, Offset:0xB, Field[29:24], Value: 1F. Result: 1F +Output PwrPerf Register: PortID: 0x3, Offset:0xB, Field[21:16], Value: 2F. Result: 2F +Output PwrPerf Register: PortID: 0x3, Offset:0xB, Field[13: 8], Value: 2F. Result: 2F +Output PwrPerf Register: PortID: 0x3, Offset:0xB, Field[ 5: 0], Value: 2F. Result: 2F +Output PwrPerf Register: PortID: 0x3, Offset:0xC, Field[29:24], Value: 2F. Result: 2F +Output PwrPerf Register: PortID: 0x3, Offset:0xC, Field[21:16], Value: 2F. Result: 2F +Output PwrPerf Register: PortID: 0x3, Offset:0xC, Field[13: 8], Value: 2F. Result: 2F +Output PwrPerf Register: PortID: 0x3, Offset:0xC, Field[ 5: 0], Value: 2B. Result: 2B +Output PwrPerf Register: PortID: 0x3, Offset:0xD, Field[21:16], Value: 2F. Result: 2F +Output PwrPerf Register: PortID: 0x3, Offset:0xD, Field[13: 8], Value: 2F. Result: 2F +Output PwrPerf Register: PortID: 0x3, Offset:0xD, Field[ 5: 0], Value: 2F. Result: 2F +Output PwrPerf Register: PortID: 0x3, Offset:0xF, Field[29:28], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0xF, Field[25:24], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0xF, Field[21:20], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0xF, Field[17:16], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0xF, Field[13:12], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0xF, Field[ 9: 8], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0xF, Field[ 5: 4], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0xF, Field[ 1: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x10, Field[ 9: 8], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x10, Field[ 5: 4], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x10, Field[ 1: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x11, Field[31:22], Value: 20. Result: 20 +Output PwrPerf Register: PortID: 0x3, Offset:0x11, Field[18:18], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x3, Offset:0x11, Field[17:12], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x3, Offset:0x11, Field[11: 8], Value: 8. Result: 8 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[31:30], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[29:28], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[27:26], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[25:24], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[23:22], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[21:20], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[19:18], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[17:16], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[15:14], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[13:12], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[11:10], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[ 9: 8], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[ 7: 6], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[ 5: 4], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[ 3: 2], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x12, Field[ 1: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x14, Field[31:31], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x14, Field[30:30], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x14, Field[13: 8], Value: 8. Result: 8 +Output PwrPerf Register: PortID: 0x3, Offset:0x14, Field[ 5: 0], Value: 10. Result: 10 +Output PwrPerf Register: PortID: 0x3, Offset:0x16, Field[31:31], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x16, Field[13: 8], Value: 3F. Result: 3F +Output PwrPerf Register: PortID: 0x3, Offset:0x16, Field[ 5: 0], Value: 8. Result: 8 +Output PwrPerf Register: PortID: 0x3, Offset:0x18, Field[31:24], Value: 20. Result: 20 +Output PwrPerf Register: PortID: 0x3, Offset:0x18, Field[23:21], Value: 6. Result: 6 +Output PwrPerf Register: PortID: 0x3, Offset:0x18, Field[13: 7], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x18, Field[ 6: 0], Value: 20. Result: 20 +Output PwrPerf Register: PortID: 0x3, Offset:0x3B, Field[23:16], Value: 4. Result: 4 +Output PwrPerf Register: PortID: 0x3, Offset:0x3B, Field[ 9: 9], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x3B, Field[ 7: 0], Value: A. Result: A +Output PwrPerf Register: PortID: 0x3, Offset:0x3C, Field[31:16], Value: FFFF. Result: FFFF +Output PwrPerf Register: PortID: 0x3, Offset:0x3C, Field[ 2: 2], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x3C, Field[ 1: 1], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x3D, Field[14:14], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x3, Offset:0x3D, Field[13:13], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x3D, Field[12:12], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x3D, Field[11:11], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x3D, Field[ 8: 8], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x3D, Field[ 7: 7], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x3D, Field[ 6: 6], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x3D, Field[ 5: 5], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x3D, Field[ 2: 2], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x3, Offset:0x3D, Field[ 1: 1], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x3, Offset:0x3D, Field[ 0: 0], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x3, Offset:0x3E, Field[31:16], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x3E, Field[ 7: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x3, Offset:0x3F, Field[31:24], Value: FF. Result: FF +Output PwrPerf Register: PortID: 0x3, Offset:0x3F, Field[23:16], Value: FF. Result: FF +Output PwrPerf Register: PortID: 0x3, Offset:0x3F, Field[15: 8], Value: FF. Result: FF +Output PwrPerf Register: PortID: 0x3, Offset:0x3F, Field[ 7: 0], Value: FF. Result: FF +Output PwrPerf Register: PortID: 0x2, Offset:0x3, Field[20:20], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x3, Field[19:19], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x2, Offset:0x3, Field[18:18], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x2, Offset:0x3, Field[17:17], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x2, Offset:0x3, Field[16:16], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x3, Field[15:15], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x2, Offset:0x3, Field[10:10], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x3, Field[ 3: 3], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x2, Offset:0x3, Field[ 2: 2], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x2, Offset:0x4, Field[18:18], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x4, Field[ 4: 1], Value: 8. Result: 8 +Output PwrPerf Register: PortID: 0x2, Offset:0x4, Field[ 0: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[27:27], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[26:26], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[25:25], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[24:24], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[23:23], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[22:22], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[21:21], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[20:20], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[19:19], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[18:18], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[17:17], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[16:16], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[15:15], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[14:14], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[13:13], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[12:12], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[11:11], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[10:10], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[ 9: 9], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[ 8: 8], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[ 7: 7], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[ 6: 6], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[ 5: 5], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[ 4: 4], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[ 3: 3], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[ 2: 2], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[ 1: 1], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x2, Offset:0x5, Field[ 0: 0], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x58, Offset:0x40, Field[ 4: 4], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x58, Offset:0x40, Field[ 4: 4], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x58, Offset:0x40, Field[ 4: 4], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x55, Offset:0x54, Field[ 1: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x55, Offset:0xFC, Field[17:17], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x55, Offset:0xFC, Field[ 9: 9], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0xA2, Offset:0xC000, Field[ 0: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x47, Offset:0xC000, Field[ 0: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x45, Offset:0xC000, Field[ 0: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x46, Offset:0xC000, Field[ 0: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x4, Offset:0x0, Field[11:11], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x4, Offset:0x0, Field[10:10], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x58, Offset:0x1E0, Field[ 4: 4], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x58, Offset:0x1E0, Field[ 0: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x58, Offset:0x1E0, Field[ 5: 5], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x58, Offset:0x1E0, Field[ 3: 3], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x58, Offset:0x1E0, Field[ 1: 1], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x58, Offset:0x1E0, Field[ 2: 2], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0xA9, Offset:0x28, Field[31: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0xA9, Offset:0x38, Field[31: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0xA9, Offset:0x1C, Field[29:28], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0xA9, Offset:0x1C, Field[25:24], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0xA9, Offset:0x1C, Field[ 1: 0], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0xA9, Offset:0x54, Field[17:16], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0xA9, Offset:0x54, Field[13:12], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0xA9, Offset:0x54, Field[15:14], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0xA9, Offset:0x54, Field[26:24], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0xA9, Offset:0x24, Field[24:20], Value: 0. Result: 1F +Output PwrPerf Register: PortID: 0x59, Offset:0x1E0, Field[ 4: 4], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x59, Offset:0x1E0, Field[ 0: 0], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x59, Offset:0x1E0, Field[ 5: 5], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x59, Offset:0x1E0, Field[ 3: 3], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x59, Offset:0x1E0, Field[ 1: 1], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x59, Offset:0x1E0, Field[ 2: 2], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0xD0, Field[ 8: 0], Value: 3F. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0x40, Field[21:19], Value: 6. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0x40, Field[10: 8], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0x40, Field[18:18], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0x50, Field[ 3: 3], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0x50, Field[ 0: 0], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0x50, Field[ 1: 1], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0x50, Field[ 2: 2], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0x50, Field[ 7: 5], Value: 2. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0x50, Field[13:13], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0x50, Field[ 4: 4], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0x50, Field[14:14], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0x50, Field[12:12], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x5A, Offset:0x50, Field[11:10], Value: 3. Result: 0 +Output PwrPerf Register: PortID: 0x48, Offset:0x4900, Field[16:16], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0xA8, Offset:0x4900, Field[16:16], Value: 1. Result: 0 +Output PwrPerf Register: PortID: 0xA0, Offset:0x180, Field[ 1: 1], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0xA0, Offset:0x180, Field[ 4: 4], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0xA0, Offset:0x180, Field[ 0: 0], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0xA0, Offset:0x180, Field[ 3: 3], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0xA0, Offset:0x180, Field[ 5: 5], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0xA0, Offset:0x180, Field[ 2: 2], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x63, Offset:0x600, Field[31:15], Value: 5. Result: 5 +Output PwrPerf Register: PortID: 0x63, Offset:0x1E0, Field[ 4: 4], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x63, Offset:0x1E0, Field[ 0: 0], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x63, Offset:0x1E0, Field[ 5: 5], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x63, Offset:0x1E0, Field[ 3: 3], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x63, Offset:0x1E0, Field[ 1: 1], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x63, Offset:0x1E0, Field[ 2: 2], Value: 1. Result: 1 +Output PwrPerf Register: PortID: 0x44, Offset:0x88, Field[ 7: 7], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x44, Offset:0x88, Field[ 1: 1], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x44, Offset:0x88, Field[ 2: 2], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x44, Offset:0x88, Field[ 3: 3], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x44, Offset:0x88, Field[ 4: 4], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x44, Offset:0x88, Field[ 6: 6], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x44, Offset:0x88, Field[ 5: 5], Value: 0. Result: 0 +Output PwrPerf Register: PortID: 0x44, Offset:0x88, Field[ 0: 0], Value: 0. Result: 0 +Config PnpSetting End !!! +Loading driver F0F6F006-DAB4-44B2-A7A1-0F72EEDCA716 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E1CAC0 +Loading driver at 0x00078DEB000 EntryPoint=0x00078DEB394 AcpiPlatform.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E1C898 +ProtectUefiImageCommon - 0x78E1CAC0 + - 0x0000000078DEB000 - 0x0000000000004C20 +mGlobalNvsArea.Area is at 0x79F8C018 +XHCI is enabled as default. SOC 0x7 +ACPI NVS XHCI:0x1 +GlobalNvsArea.Area->I2CTouchAddress: [00] +Auto detect mode------------start +SOC B0 and later: eMMC 4.5 Configuration +mGlobalNvsArea.Area->emmcVersion = 1 +JP1 is not set to be MSFT IOT configuration. +InstallProtocolInterface: 074E1E48-8132-47A1-8C2C-3F14AD9A66DC 78DEF9E0 +PcRtc: Write 0x19 to CMOS location 0x32 +ApicPtr->AcpiLocalApic.AcpiProcessorId = 1, MaximumNumberOfCPUs = 4 +ApicPtr->AcpiLocalApic.AcpiProcessorId = 2, MaximumNumberOfCPUs = 4 +ApicPtr->AcpiLocalApic.AcpiProcessorId = 3, MaximumNumberOfCPUs = 4 +ApicPtr->AcpiLocalApic.AcpiProcessorId = 4, MaximumNumberOfCPUs = 4 +Loading driver 4096267B-DA0A-42EB-B5EB-FEF31D207CB4 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E16D40 +Loading driver at 0x00078BD7000 EntryPoint=0x00078BD74DC FmpDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E16698 +ProtectUefiImageCommon - 0x78E16D40 + - 0x0000000078BD7000 - 0x0000000000082BC0 +PcdFlashAreaBaseAddress - 0xFF800000 +FmpDxe(Minnow Max System Firmware Device): Test key detected in PcdFmpDevicePkcs7CertBufferXdr. +FmpDxe(Minnow Max System Firmware Device): Lock GUID: 02CE967A-DD7E-4FFC-9EE7-810CF0470880 +FmpDxe(Minnow Max System Firmware Device): FmpDeviceLib registration returned EFI_UNSUPPORTED. Installing single FMP instance. +FmpDxe(Minnow Max System Firmware Device): Fall back to ImageTypeIdGuid of gEfiCallerIdGuid +FmpDxe(Minnow Max System Firmware Device): Variable 4096267B-DA0A-42EB-B5EB-FEF31D207CB4 FmpVersion +FmpDxe(Minnow Max System Firmware Device): Variable 4096267B-DA0A-42EB-B5EB-FEF31D207CB4 FmpLsv +FmpDxe(Minnow Max System Firmware Device): Variable 4096267B-DA0A-42EB-B5EB-FEF31D207CB4 LastAttemptStatus +FmpDxe(Minnow Max System Firmware Device): Variable 4096267B-DA0A-42EB-B5EB-FEF31D207CB4 LastAttemptVersion +FmpDxe(Minnow Max System Firmware Device): Variable 4096267B-DA0A-42EB-B5EB-FEF31D207CB4 FmpState +FmpDxe(Minnow Max System Firmware Device): Failed to get the controller state. Status = Not Found +FmpDxe(Minnow Max System Firmware Device): Create controller state +FvbProtocolWrite: Lba: 0x0 Offset: 0x1F80 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x1F82 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x1FBC NumBytes: 0x26, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x1F82 NumBytes: 0x1, Buffer: 0x7B6DF01A +FmpDxe(Minnow Max System Firmware Device): All variables registered to lock +InstallProtocolInterface: 86C77A67-0B97-4633-A187-49104D0685C7 78E169A8 +InstallProtocolInterface: 1849BDA2-6952-4E86-A1DB-559A3C479DF1 78C52990 +Loading driver 79179BFD-704D-4C90-9E02-0AB8D968C18A +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E060C0 +Loading driver at 0x00078B55000 EntryPoint=0x00078B554AC FmpDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E16718 +ProtectUefiImageCommon - 0x78E060C0 + - 0x0000000078B55000 - 0x0000000000081F00 +FmpDxe(Sample Firmware Device): Lock GUID: 02CE967A-DD7E-4FFC-9EE7-810CF0470880 +FmpDxe(Sample Firmware Device): FmpDeviceLib registration returned EFI_UNSUPPORTED. Installing single FMP instance. +FmpDxe(Sample Firmware Device): Fall back to ImageTypeIdGuid of gEfiCallerIdGuid +FmpDxe(Sample Firmware Device): Variable 79179BFD-704D-4C90-9E02-0AB8D968C18A FmpVersion +FmpDxe(Sample Firmware Device): Variable 79179BFD-704D-4C90-9E02-0AB8D968C18A FmpLsv +FmpDxe(Sample Firmware Device): Variable 79179BFD-704D-4C90-9E02-0AB8D968C18A LastAttemptStatus +FmpDxe(Sample Firmware Device): Variable 79179BFD-704D-4C90-9E02-0AB8D968C18A LastAttemptVersion +FmpDxe(Sample Firmware Device): Variable 79179BFD-704D-4C90-9E02-0AB8D968C18A FmpState +FmpDxe(Sample Firmware Device): Failed to get the controller state. Status = Not Found +FmpDxe(Sample Firmware Device): Create controller state +FvbProtocolWrite: Lba: 0x0 Offset: 0x1FE4 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x1FE6 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2020 NumBytes: 0x26, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x1FE6 NumBytes: 0x1, Buffer: 0x7B6DF01A +FmpDxe(Sample Firmware Device): GetVersionString() unsupported in FmpDeviceLib. +FmpDxe(Sample Firmware Device): All variables registered to lock +InstallProtocolInterface: 86C77A67-0B97-4633-A187-49104D0685C7 78E063A8 +InstallProtocolInterface: 1849BDA2-6952-4E86-A1DB-559A3C479DF1 78BCFD40 +Loading driver 149DA854-7D19-4FAA-A91E-862EA1324BE6 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E05C40 +Loading driver at 0x00078AD3000 EntryPoint=0x00078AD34AC FmpDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E05118 +ProtectUefiImageCommon - 0x78E05C40 + - 0x0000000078AD3000 - 0x0000000000081F00 +FmpDxe(Sample Firmware Device): Lock GUID: 02CE967A-DD7E-4FFC-9EE7-810CF0470880 +FmpDxe(Sample Firmware Device): FmpDeviceLib registration returned EFI_UNSUPPORTED. Installing single FMP instance. +FmpDxe(Sample Firmware Device): Fall back to ImageTypeIdGuid of gEfiCallerIdGuid +FmpDxe(Sample Firmware Device): Variable 149DA854-7D19-4FAA-A91E-862EA1324BE6 FmpVersion +FmpDxe(Sample Firmware Device): Variable 149DA854-7D19-4FAA-A91E-862EA1324BE6 FmpLsv +FmpDxe(Sample Firmware Device): Variable 149DA854-7D19-4FAA-A91E-862EA1324BE6 LastAttemptStatus +FmpDxe(Sample Firmware Device): Variable 149DA854-7D19-4FAA-A91E-862EA1324BE6 LastAttemptVersion +FmpDxe(Sample Firmware Device): Variable 149DA854-7D19-4FAA-A91E-862EA1324BE6 FmpState +FmpDxe(Sample Firmware Device): Failed to get the controller state. Status = Not Found +FmpDxe(Sample Firmware Device): Create controller state +FvbProtocolWrite: Lba: 0x0 Offset: 0x2048 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x204A NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2084 NumBytes: 0x26, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x204A NumBytes: 0x1, Buffer: 0x7B6DF01A +FmpDxe(Sample Firmware Device): GetVersionString() unsupported in FmpDeviceLib. +FmpDxe(Sample Firmware Device): All variables registered to lock +InstallProtocolInterface: 86C77A67-0B97-4633-A187-49104D0685C7 78E051A8 +InstallProtocolInterface: 1849BDA2-6952-4E86-A1DB-559A3C479DF1 78B4DD40 +Loading driver 72E2945A-00DA-448E-9AA7-075AD840F9D4 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E04040 +Loading driver at 0x00078A51000 EntryPoint=0x00078A514AC FmpDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E04D18 +ProtectUefiImageCommon - 0x78E04040 + - 0x0000000078A51000 - 0x0000000000081F00 +FmpDxe(Sample Firmware Device): Lock GUID: 02CE967A-DD7E-4FFC-9EE7-810CF0470880 +FmpDxe(Sample Firmware Device): FmpDeviceLib registration returned EFI_UNSUPPORTED. Installing single FMP instance. +FmpDxe(Sample Firmware Device): Fall back to ImageTypeIdGuid of gEfiCallerIdGuid +FmpDxe(Sample Firmware Device): Variable 72E2945A-00DA-448E-9AA7-075AD840F9D4 FmpVersion +FmpDxe(Sample Firmware Device): Variable 72E2945A-00DA-448E-9AA7-075AD840F9D4 FmpLsv +FmpDxe(Sample Firmware Device): Variable 72E2945A-00DA-448E-9AA7-075AD840F9D4 LastAttemptStatus +FmpDxe(Sample Firmware Device): Variable 72E2945A-00DA-448E-9AA7-075AD840F9D4 LastAttemptVersion +FmpDxe(Sample Firmware Device): Variable 72E2945A-00DA-448E-9AA7-075AD840F9D4 FmpState +FmpDxe(Sample Firmware Device): Failed to get the controller state. Status = Not Found +FmpDxe(Sample Firmware Device): Create controller state +FvbProtocolWrite: Lba: 0x0 Offset: 0x20AC NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x20AE NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x20E8 NumBytes: 0x26, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x20AE NumBytes: 0x1, Buffer: 0x7B6DF01A +FmpDxe(Sample Firmware Device): GetVersionString() unsupported in FmpDeviceLib. +FmpDxe(Sample Firmware Device): All variables registered to lock +InstallProtocolInterface: 86C77A67-0B97-4633-A187-49104D0685C7 78E04AA8 +InstallProtocolInterface: 1849BDA2-6952-4E86-A1DB-559A3C479DF1 78ACBD40 +Loading driver 0565365C-2FE1-4F88-B3BE-624C04623A20 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E045C0 +Loading driver at 0x00078D96000 EntryPoint=0x00078D96434 MicrocodeUpdateDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78E03F18 +ProtectUefiImageCommon - 0x78E045C0 + - 0x0000000078D96000 - 0x0000000000007360 +PcdFlashAreaBaseAddress - 0xFF800000 +GetLastAttempt - Not Found +GetLastAttempt Version - 0x0, State - 0x0 +CpuDxe: 5-Level Paging = 0 +CpuDxe: 5-Level Paging = 0 +CpuDxe: 5-Level Paging = 0 +Microcode Region - 0xFFC00060 - 0x3FFA0 +Microcode Region - 0xFFC00060 - 0x3FFA0 +ProcessorInfo: + ProcessorCount - 0x4 + BspIndex - 0x0 + ProcessorInfo[0x0] - 0x00030679, 0x00, 0x00000909, (0x3) + ProcessorInfo[0x1] - 0x00030679, 0x00, 0x00000909, (0x3) + ProcessorInfo[0x2] - 0x00030679, 0x00, 0x00000909, (0x3) + ProcessorInfo[0x3] - 0x00030679, 0x00, 0x00000909, (0x3) +MicrocodeInfo: + MicrocodeRegion - 0xFFC00060 - 0x3FFA0 + MicrocodeCount - 0x4 + MicrocodeInfo[0x0] - 0xFFC00060, 0x0000CC00, (0x0) + MicrocodeInfo[0x1] - 0xFFC0D060, 0x0000C800, (0x0) + MicrocodeInfo[0x2] - 0xFFC19860, 0x0000CC00, (0x0) + MicrocodeInfo[0x3] - 0xFFC26860, 0x0000CC00, (0x1) +InstallProtocolInterface: 86C77A67-0B97-4633-A187-49104D0685C7 78E03D20 +Evaluate SMM DEPEX for FFS(D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC) + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(1A819E49-D8EE-48CB-9A9C-0AA0D2810A38) = FALSE + PUSH GUID(E287D20B-D897-4E1E-A5D9-977763936A04) = TRUE + PUSH GUID(843DC720-AB1E-42CB-9357-8A0078F3561B) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(ACAEAA7A-C039-4424-88DA-F42212EA0E55) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(3920405B-C897-44DA-88F3-4C498A6FF736) = TRUE + PUSH GUID(D31F0400-7D16-4316-BF88-6065883B402B) = FALSE + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(99C20A37-042A-46E2-80F4-E4027FDBC86F) + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(1B1183FA-1823-46A7-8872-9C578755409D) = TRUE + PUSH GUID(456D2859-A84B-4E47-A2EE-3276D886997D) = TRUE + PUSH GUID(C50B323E-9075-4F2A-AC8E-D2596A1085CC) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(1E5668E2-8481-11D4-BCF1-0080C73C8881) = TRUE + PUSH GUID(6441F818-6362-4E44-B570-7DBA31DD2453) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(41E89AB0-BD3D-44B6-A431-E4836EFBF2CB) + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = TRUE + PUSH GUID(DDABFEAC-EF63-452C-8F39-ED7FAED8265E) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(5122FA7B-17A3-4A8B-89AE-A93ADE92EADF) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(18A3C6DC-5EEA-48C8-A1C1-B53389F98999) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = TRUE + PUSH GUID(3FDDA605-A76E-4F46-AD29-12F4531B3D08) = TRUE + PUSH GUID(456D2859-A84B-4E47-A2EE-3276D886997D) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(99EC6206-AA45-4CAE-B630-866755241C8A) + PUSH GUID(5BAB88BA-E0E2-4674-B6AD-B812F6881CD6) = FALSE + PUSH GUID(2F707EBB-4A1A-11D4-9A38-0090273FC14D) = TRUE + PUSH GUID(AD61F191-AE5F-4C0E-B9FA-E869D288C64F) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = TRUE + PUSH GUID(220E73B6-6BDB-4413-8405-B974B108619A) = TRUE + PUSH GUID(EF9FC172-A1B2-4693-B327-6D32FC416042) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E03698 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E74C0 +Loading SMM driver at 0x0007B562000 EntryPoint=0x0007B563274 PlatformSmm.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SmmLockBoxSmmLib SmmLockBoxMmConstructor - Enter +SmmLockBoxSmmLib SmmLockBoxContext - already installed +SmmLockBoxSmmLib SmmLockBoxMmConstructor - Exit +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78E03318 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E66C0 +Loading SMM driver at 0x0007B54A000 EntryPoint=0x0007B54B2C0 PowerManagement2.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Enter +SmmLockBoxSmmLib SmmLockBoxContext - already installed +SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Exit + + + == == CreateFvidTable == == + +BusRatioRange:[0011] StepSize:[0001] Turbo:[0000] +NumberOfStates:[0012] +BusRatioRange:[0011] StepSize:[0002] Turbo:[0000] +FVID[0].FvidHeader.MaxVid = 40 +FVID[0].FvidHeader.MaxBusRatio = 17 +FVID[0].FvidHeader.Gv3States = 9 + +FVID[01].State = 0 +FVID[01].BusRatio = 17 +FVID[01].vid = 40 +FVID[01].Power = 7D0 + + + -->REST of VID ENTRY +FVID[02].State = 1 +FVID[02].BusRatio = 15 +FVID[02].Vid = 3E +FVID[02].Power = 72B + +FVID[03].State = 2 +FVID[03].BusRatio = 13 +FVID[03].Vid = 3B +FVID[03].Power = 686 + +FVID[04].State = 3 +FVID[04].BusRatio = 11 +FVID[04].Vid = 38 +FVID[04].Power = 5E1 + +FVID[05].State = 4 +FVID[05].BusRatio = F +FVID[05].Vid = 35 +FVID[05].Power = 53D + +FVID[06].State = 5 +FVID[06].BusRatio = D +FVID[06].Vid = 32 +FVID[06].Power = 498 + +FVID[07].State = 6 +FVID[07].BusRatio = B +FVID[07].Vid = 30 +FVID[07].Power = 3F3 + +FVID[08].State = 7 +FVID[08].BusRatio = 9 +FVID[08].Vid = 2D +FVID[08].Power = 34F + +FVID[09].State = 8 +FVID[09].BusRatio = 7 +FVID[09].Vid = 2A +FVID[09].Power = 2AA + + + +InitializePpmAcpiTable(): InstallAcpiTable() +InitializePpmAcpiTable(): InstallAcpiTable() Success +InitializePpmAcpiTable(): InstallAcpiTable() +InitializePpmAcpiTable(): InstallAcpiTable() Success +InitializePpmAcpiTable(): InstallAcpiTable() +InitializePpmAcpiTable(): InstallAcpiTable() Success +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DF2098 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E64C0 +Loading SMM driver at 0x0007B53B000 EntryPoint=0x0007B53C23C DigitalThermalSensor.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +Evaluate SMM DEPEX for FFS(D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC) + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(1A819E49-D8EE-48CB-9A9C-0AA0D2810A38) = FALSE + PUSH GUID(E287D20B-D897-4E1E-A5D9-977763936A04) = TRUE + PUSH GUID(843DC720-AB1E-42CB-9357-8A0078F3561B) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(ACAEAA7A-C039-4424-88DA-F42212EA0E55) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(3920405B-C897-44DA-88F3-4C498A6FF736) = TRUE + PUSH GUID(D31F0400-7D16-4316-BF88-6065883B402B) = FALSE + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(99EC6206-AA45-4CAE-B630-866755241C8A) + PUSH GUID(5BAB88BA-E0E2-4674-B6AD-B812F6881CD6) = FALSE + PUSH GUID(2F707EBB-4A1A-11D4-9A38-0090273FC14D) = TRUE + PUSH GUID(AD61F191-AE5F-4C0E-B9FA-E869D288C64F) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = TRUE + PUSH GUID(220E73B6-6BDB-4413-8405-B974B108619A) = TRUE + PUSH GUID(EF9FC172-A1B2-4693-B327-6D32FC416042) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = FALSE +Loading driver 056E7324-A718-465B-9A84-228F06642B4F +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DF2340 +Loading driver at 0x00078D82000 EntryPoint=0x00078D82444 PlatformDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DF2D98 +ProtectUefiImageCommon - 0x78DF2340 + - 0x0000000078D82000 - 0x0000000000009C20 +InstallProtocolInterface: 400B4476-3081-11D6-87ED-00062945C3B9 78D8AA50 +InstallProtocolInterface: E227C522-D5FE-4A53-87B1-0FBE570F98E9 78D8AD50 +SaveSetupRecoveryVar() Entry +FvbProtocolWrite: Lba: 0x0 Offset: 0x2110 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2112 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x214C NumBytes: 0x3B9, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2112 NumBytes: 0x1, Buffer: 0x7B6DF01A +!!! DEPRECATED INTERFACE !!! VariableLockRequestToLock() will go away soon! +!!! DEPRECATED INTERFACE !!! Please move to use Variable Policy! +!!! DEPRECATED INTERFACE !!! Variable: EC87D643-EBA4-4BB5-A1E5-3F3E36B20DA9 SetupRecovery +InitPchPlatformPolicy() - Start +XHCI is enabled as default. SOC 0x7 +InitPchPlatformPolicy() DxePlatformPchPolicy->EhciPllCfgEnable = 0x1 +Auto Detect: SOC B0 and later: SCC eMMC 4.5 Configuration +InstallProtocolInterface: 1A819E49-D8EE-48CB-9A9C-0AA0D2810A38 78D8AE20 +InitPchPlatformPolicy() - End +InstallProtocolInterface: 5BAB88BA-E0E2-4674-B6AD-B812F6881CD6 78D8AF40 +InstallProtocolInterface: 3C485EA4-449A-46CE-BB08-2A336EA96B4E 78D8ADF0 +InstallProtocolInterface: EF7BF7D6-F8FF-4A76-8247-C0D0D1CC49C0 78D8AA90 +InstallProtocolInterface: A6A79162-E325-4C30-BCC3-59373064EFB3 78D8AD80 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2508 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x250A NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2544 NumBytes: 0x1D, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x250A NumBytes: 0x1, Buffer: 0x7B6DF01A +Loading driver FF0C8745-3270-4439-B74F-3E45F8C77064 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DF0CC0 +Loading driver at 0x00078D5C000 EntryPoint=0x00078D5F4B0 +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DF0B18 +ProtectUefiImageCommon - 0x78DF0CC0 + - 0x0000000078D5C000 - 0x0000000000012500 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78D5F290 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78D5F1C0 +InstallProtocolInterface: 651B7EBD-CE13-41D0-82E5-A063ABBE9BB6 78D5F1D8 +Loading driver B8E62775-BB0A-43F0-A843-5BE8B14F8CCD +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DF03C0 +Loading driver at 0x00078D9E000 EntryPoint=0x00078D9E3B4 BootGraphicsResourceTableDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DEAF98 +ProtectUefiImageCommon - 0x78DF03C0 + - 0x0000000078D9E000 - 0x0000000000003480 +InstallProtocolInterface: CDEA2BD3-FC25-4C1C-B97C-B31186064990 78DA11B8 +InstallProtocolInterface: 4B5DC1DF-1EAA-48B2-A7E9-EAC489A00B5C 78DA11A8 +Loading driver 93B80004-9FB3-11D4-9A3A-0090273FC14D +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DEA140 +Loading driver at 0x00078CB5000 EntryPoint=0x00078CB53D4 PciBusDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DEA998 +ProtectUefiImageCommon - 0x78DEA140 + - 0x0000000078CB5000 - 0x0000000000013780 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78CC7388 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78CC73D0 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78CC73E8 +InstallProtocolInterface: 19CB87AB-2CB9-4665-8360-DDCF6054F79D 78CC73B8 +Loading driver 5A38B969-CD6A-4814-82E6-559F840BBC58 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DE9BC0 +Loading driver at 0x00078D78000 EntryPoint=0x00078D783F0 ISPDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DE9A98 +ProtectUefiImageCommon - 0x78DE9BC0 + - 0x0000000078D78000 - 0x00000000000099A0 +Loading driver F749DEBC-42E6-4F59-821E-1E94EE9FBBB1 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DE9240 +Loading driver at 0x00078D8C000 EntryPoint=0x00078D8C3B4 PcuSio.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DE9598 +ProtectUefiImageCommon - 0x78DE9240 + - 0x0000000078D8C000 - 0x0000000000004280 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78D8FE88 +Loading driver E2775B47-D453-4EE3-ADA7-391A1B05AC17 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DE8040 +Loading driver at 0x00078D54000 EntryPoint=0x00078D543B4 PciSioSerialDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DE8E98 +ProtectUefiImageCommon - 0x78DE8040 + - 0x0000000078D54000 - 0x0000000000007420 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78D5AC38 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78D5AD88 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78D5AD70 +Loading driver 8E325979-3FE1-4927-AAE2-8F5C4BD2AF0D +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DE83C0 +Loading driver at 0x00078CA9000 EntryPoint=0x00078CA93B4 SdMmcPciHcDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DE8698 +ProtectUefiImageCommon - 0x78DE83C0 + - 0x0000000078CA9000 - 0x000000000000B820 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78CB3BF8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78CB3E48 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78CB3E60 +Loading driver 2145F72F-E6F1-4440-A828-59DC9AAB5F89 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DA5CC0 +Loading driver at 0x00078CC9000 EntryPoint=0x00078CC93B4 EmmcDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DA5B18 +ProtectUefiImageCommon - 0x78DA5CC0 + - 0x0000000078CC9000 - 0x00000000000091E0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78CD18F8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78CD1A60 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78CD1A48 +Loading driver 430AC2F7-EEC6-4093-94F7-9F825A7C1C40 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DA52C0 +Loading driver at 0x00078CD5000 EntryPoint=0x00078CD53B4 SdDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DA5918 +ProtectUefiImageCommon - 0x78DA52C0 + - 0x0000000078CD5000 - 0x00000000000071A0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78CDB988 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78CDBB48 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78CDBB30 +Loading driver 6B38F7B4-AD98-40E9-9093-ACA2B5A253C4 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DA40C0 +Loading driver at 0x00078CA3000 EntryPoint=0x00078CA33B4 DiskIoDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DA4A18 +ProtectUefiImageCommon - 0x78DA40C0 + - 0x0000000078CA3000 - 0x0000000000005560 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78CA7FD8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78CA8098 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78CA80B0 +Loading driver 1FA1F39E-FEFF-4AAE-BD7B-38A070A3B609 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DA44C0 +Loading driver at 0x00078C9B000 EntryPoint=0x00078C9B3D4 PartitionDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DA4818 +ProtectUefiImageCommon - 0x78DA44C0 + - 0x0000000078C9B000 - 0x0000000000007600 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78CA1EF0 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78CA1F50 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78CA1F38 +Loading driver CD3BAFB6-50FB-4FE8-8E4E-AB74D2C1A600 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DA30C0 +Loading driver at 0x00078D75000 EntryPoint=0x00078D753B4 EnglishDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DA3B18 +ProtectUefiImageCommon - 0x78DA30C0 + - 0x0000000078D75000 - 0x0000000000002CE0 +InstallProtocolInterface: 1D85CD7F-F43D-11D2-9A0C-0090273FC14D 78D777A8 +InstallProtocolInterface: A4C751FC-23AE-4C3E-92E9-4964CF63F349 78D777E0 +Loading driver BB65942B-521F-4EC3-BAF9-A92540CF60D2 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DA2040 +Loading driver at 0x00078C8B000 EntryPoint=0x00078C8B3E0 SataController.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DA3498 +ProtectUefiImageCommon - 0x78DA2040 + - 0x0000000078C8B000 - 0x0000000000007600 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78C91FA0 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78C91FD0 +Loading driver 19DF145A-B1D4-453F-8507-38816676D7F6 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78DA22C0 +Loading driver at 0x00078C83000 EntryPoint=0x00078C833B4 AtaBusDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DA2C98 +ProtectUefiImageCommon - 0x78DA22C0 + - 0x0000000078C83000 - 0x00000000000074E0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78C89B60 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78C89D88 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78C89D70 +Loading driver 5E523CB4-D397-4986-87BD-A6DD8B22F455 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D95040 +Loading driver at 0x00078C69000 EntryPoint=0x00078C693D4 AtaAtapiPassThruDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78DA2798 +ProtectUefiImageCommon - 0x78D95040 + - 0x0000000078C69000 - 0x000000000000C560 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78C749E8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78C74A18 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78C74A30 +Loading driver 0167CCC4-D0F7-4F21-A3EF-9E64B7CDCE8B +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D959C0 +Loading driver at 0x00078C95000 EntryPoint=0x00078C953B4 ScsiBus.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D95818 +ProtectUefiImageCommon - 0x78D959C0 + - 0x0000000078C95000 - 0x00000000000050A0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78C99B68 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78C99B98 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78C99BB0 +Loading driver 0A66E322-3740-4CCE-AD62-BD172CECCA35 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D94040 +Loading driver at 0x00078C5D000 EntryPoint=0x00078C5D3B4 ScsiDisk.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D94D18 +ProtectUefiImageCommon - 0x78D94040 + - 0x0000000078C5D000 - 0x000000000000B9A0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78C68008 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78C68080 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78C68068 +Loading driver 51CCF399-4FDF-4E55-A45B-E123F84D456A +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D94440 +Loading driver at 0x00078C7E000 EntryPoint=0x00078C7E3D4 ConPlatformDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D94C18 +ProtectUefiImageCommon - 0x78D94440 + - 0x0000000078C7E000 - 0x0000000000004FA0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78C82A98 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78C82AE0 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78C82AC8 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78C82A68 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78C82AE0 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78C82AC8 +Loading driver 408EDCEC-CF6D-477C-A5A8-B4844E3DE281 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D930C0 +Loading driver at 0x00078A3F000 EntryPoint=0x00078A3F3B4 ConSplitterDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D93D98 +ProtectUefiImageCommon - 0x78D930C0 + - 0x0000000078A3F000 - 0x0000000000008EA0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78A47110 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78A474C8 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78A47438 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78A472B0 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78A47498 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78A47450 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78A47280 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78A47408 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78A47468 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78A46F38 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78A47480 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78A47420 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78A47140 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78A474B0 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78A473F0 +InstallProtocolInterface: 387477C1-69C7-11D2-8E39-00A0C969723B 78A46F80 +InstallProtocolInterface: DD9E7534-7762-4698-8C14-F58517A625AA 78A46FB0 +InstallProtocolInterface: 31878C87-0B75-11D5-9A4F-0090273FC14D 78A47020 +InstallProtocolInterface: 8D59D32B-C655-4AE9-9B15-F25904992A43 78A47078 +InstallProtocolInterface: 387477C2-69C7-11D2-8E39-00A0C969723B 78A47180 +InstallProtocolInterface: 387477C2-69C7-11D2-8E39-00A0C969723B 78A472F0 +Loading driver CCCB0C28-4B24-11D5-9A5A-0090273FC14D +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D744C0 +Loading driver at 0x00078A4A000 EntryPoint=0x00078A4A3D4 GraphicsConsoleDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D93398 +ProtectUefiImageCommon - 0x78D744C0 + - 0x0000000078A4A000 - 0x0000000000006B40 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78A4F010 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78A50638 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78A50620 +Loading driver 9E863906-A40F-4875-977F-5B93FF237FC6 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D73140 +Loading driver at 0x00078A2B000 EntryPoint=0x00078A2B3D4 TerminalDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D73398 +ProtectUefiImageCommon - 0x78D73140 + - 0x0000000078A2B000 - 0x0000000000009300 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78A33938 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78A33AC8 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78A33AB0 +Loading driver BDFE430E-8F2A-4DB0-9991-6F856594777E +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D72B40 +Loading driver at 0x00078A21000 EntryPoint=0x00078A213B4 EhciDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D73598 +ProtectUefiImageCommon - 0x78D72B40 + - 0x0000000078A21000 - 0x0000000000009BE0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78A2A328 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78A2A3A8 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78A2A390 +Loading driver 2FB92EFA-2EE0-4BAE-9EB6-7464125E1EF7 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D721C0 +Loading driver at 0x00078A18000 EntryPoint=0x00078A183B4 UhciDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D72518 +ProtectUefiImageCommon - 0x78D721C0 + - 0x0000000078A18000 - 0x0000000000008480 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78A1FC08 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78A1FC50 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78A1FC38 +Loading driver 9FB4B4A7-42C0-4BCD-8540-9BCC6711F83E +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D71B40 +Loading driver at 0x00078A38000 EntryPoint=0x00078A383B4 UsbMassStorageDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D71098 +ProtectUefiImageCommon - 0x78D71B40 + - 0x0000000078A38000 - 0x0000000000006E80 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78A3E678 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78A3E750 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78A3E738 +Loading driver 2D2E62CF-9ECF-43B7-8219-94E7FC713DFE +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D71240 +Loading driver at 0x00078A10000 EntryPoint=0x00078A103D4 UsbKbDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D71598 +ProtectUefiImageCommon - 0x78D71240 + - 0x0000000078A10000 - 0x00000000000077E0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78A169A8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78A170E0 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78A170C8 +Loading driver 2D2E62AA-9ECF-43B7-8219-94E7FC713DFE +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D70CC0 +Loading driver at 0x00078A0A000 EntryPoint=0x00078A0A3B4 UsbMouseDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D70918 +ProtectUefiImageCommon - 0x78D70CC0 + - 0x0000000078A0A000 - 0x0000000000005020 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78A0EAF8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78A0EB28 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78A0EB40 +Loading driver 240612B7-A063-11D4-9A3A-0090273FC14D +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D70340 +Loading driver at 0x000789F4000 EntryPoint=0x000789F43D4 UsbBusDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D70A18 +ProtectUefiImageCommon - 0x78D70340 + - 0x00000000789F4000 - 0x000000000000A980 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 789FDED8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 789FDF20 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 789FDF08 +Loading driver B7F50E91-A759-412C-ADE4-DCD03E7F7C28 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D6F0C0 +Loading driver at 0x000789D6000 EntryPoint=0x000789D63B4 XhciDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D6F918 +ProtectUefiImageCommon - 0x78D6F0C0 + - 0x00000000789D6000 - 0x000000000000E0E0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 789E3578 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 789E36D8 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 789E36C0 +Loading driver 4EFFB560-B28B-4E57-9DAD-4344E32EA3BA +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78D6F3C0 +Loading driver at 0x000789EB000 EntryPoint=0x000789EB444 MiscSubclass.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78D53F98 +ProtectUefiImageCommon - 0x78D6F3C0 + - 0x00000000789EB000 - 0x0000000000008CE0 +PlatformInfoHob->BoardId [0xB0] +DXE get BIOS ID from FV successfully +BIOS ID: MNW2MAXW.X64.0090.D01.2112181640 +GetBiosVersionDateTime :MNW2MAXW.X64.0090.D01.2112181640 12/18/2021 16:40 +SmbiosAdd: Smbios type 0 with size 0x53 is added to 32-bit table +SmbiosAdd: Smbios type 0 with size 0x53 is added to 64-bit table +SmbiosCreateTable: Initialize 32-bit entry point structure +SmbiosCreateTable() re-allocate SMBIOS 32-bit table +SmbiosCreateTable: Initialize 64-bit entry point structure +SmbiosCreate64BitTable() re-allocate SMBIOS 64-bit table +Create Smbios Manu callback. +MAC Address: 000000000000 +SmbiosAdd: Smbios type 2 with size 0x6F is added to 32-bit table +SmbiosAdd: Smbios type 2 with size 0x6F is added to 64-bit table +SmbiosAdd: Smbios type 3 with size 0x23 is added to 32-bit table +SmbiosAdd: Smbios type 3 with size 0x23 is added to 64-bit table +MiscProcessorCache(): Cache Type = 1 Cache Level = 1 Size = 6000 +SmbiosAdd: Smbios type 7 with size 0x21 is added to 32-bit table +SmbiosAdd: Smbios type 7 with size 0x21 is added to 64-bit table +MiscProcessorCache(): Cache Type = 2 Cache Level = 1 Size = 8000 +SmbiosAdd: Smbios type 7 with size 0x21 is added to 32-bit table +SmbiosAdd: Smbios type 7 with size 0x21 is added to 64-bit table +MiscProcessorCache(): Cache Type = 3 Cache Level = 2 Size = 100000 +SmbiosAdd: Smbios type 7 with size 0x21 is added to 32-bit table +SmbiosAdd: Smbios type 7 with size 0x21 is added to 64-bit table +Processor Brand String = Intel(R) Atom(TM) CPU E3845 @ 1.91GHz +Processor Unicode Brand String = Intel(R) Atom(TM) CPU E3845 @ 1.91GHz +SmbiosAdd: Smbios type 4 with size 0x69 is added to 32-bit table +SmbiosAdd: Smbios type 4 with size 0x69 is added to 64-bit table +SmbiosAdd: Smbios type 16 with size 0x23 is added to 32-bit table +SmbiosAdd: Smbios type 16 with size 0x23 is added to 64-bit table +SmbiosAdd: Smbios type 17 with size 0x78 is added to 32-bit table +SmbiosAdd: Smbios type 17 with size 0x78 is added to 64-bit table +SmbiosAdd: Smbios type 17 with size 0x78 is added to 32-bit table +SmbiosAdd: Smbios type 17 with size 0x78 is added to 64-bit table +SmbiosAdd: Smbios type 19 with size 0x2B is added to 32-bit table +SmbiosAdd: Smbios type 19 with size 0x2B is added to 64-bit table +SmbiosAdd: Smbios type 8 with size 0x19 is added to 32-bit table +SmbiosAdd: Smbios type 8 with size 0x19 is added to 64-bit table +SmbiosAdd: Smbios type 8 with size 0x19 is added to 32-bit table +SmbiosAdd: Smbios type 8 with size 0x19 is added to 64-bit table +SmbiosAdd: Smbios type 8 with size 0x17 is added to 32-bit table +SmbiosAdd: Smbios type 8 with size 0x17 is added to 64-bit table +SmbiosAdd: Smbios type 9 with size 0x2D is added to 32-bit table +SmbiosAdd: Smbios type 9 with size 0x2D is added to 64-bit table +SmbiosAdd: Smbios type 9 with size 0x2D is added to 32-bit table +SmbiosAdd: Smbios type 9 with size 0x2D is added to 64-bit table +SmbiosAdd: Smbios type 9 with size 0x2A is added to 32-bit table +SmbiosAdd: Smbios type 9 with size 0x2A is added to 64-bit table +SmbiosAdd: Smbios type 9 with size 0x2C is added to 32-bit table +SmbiosAdd: Smbios type 9 with size 0x2C is added to 64-bit table +SmbiosAdd: Smbios type 9 with size 0x2C is added to 32-bit table +SmbiosAdd: Smbios type 9 with size 0x2C is added to 64-bit table +SmbiosAdd: Smbios type 9 with size 0x2C is added to 32-bit table +SmbiosAdd: Smbios type 9 with size 0x2C is added to 64-bit table +SmbiosAdd: Smbios type 9 with size 0x28 is added to 32-bit table +SmbiosAdd: Smbios type 9 with size 0x28 is added to 64-bit table +SmbiosAdd: Smbios type 9 with size 0x28 is added to 32-bit table +SmbiosAdd: Smbios type 9 with size 0x28 is added to 64-bit table +SmbiosAdd: Smbios type 9 with size 0x28 is added to 32-bit table +SmbiosAdd: Smbios type 9 with size 0x28 is added to 64-bit table +SmbiosAdd: Smbios type 10 with size 0x28 is added to 32-bit table +SmbiosAdd: Smbios type 10 with size 0x28 is added to 64-bit table +SmbiosAdd: Smbios type 10 with size 0x20 is added to 32-bit table +SmbiosAdd: Smbios type 10 with size 0x20 is added to 64-bit table +SmbiosAdd: Smbios type 13 with size 0x1C is added to 32-bit table +SmbiosAdd: Smbios type 13 with size 0x1C is added to 64-bit table +SmbiosAdd: Smbios type 32 with size 0xD is added to 32-bit table +SmbiosAdd: Smbios type 32 with size 0xD is added to 64-bit table +Loading driver 961578FE-B6B7-44C3-AF35-6BC705CD2B1F +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C7B8C0 +Loading driver at 0x000789BE000 EntryPoint=0x000789BE3DC Fat.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C7B798 +ProtectUefiImageCommon - 0x78C7B8C0 + - 0x00000000789BE000 - 0x000000000000B6C0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 789C89A8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 789C89F0 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 789C89D8 +Loading driver A2F436EA-A127-4EF8-957C-8048606FF670 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C7B540 +Loading driver at 0x000789CD000 EntryPoint=0x000789CD558 SnpDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C7AE98 +ProtectUefiImageCommon - 0x78C7B540 + - 0x00000000789CD000 - 0x00000000000080E0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 789D4A58 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 789D4AA0 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 789D4A88 +Loading driver 025BBFC7-E6A9-4B8B-82AD-6815A1AEAF4A +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C7A7C0 +Loading driver at 0x000789A6000 EntryPoint=0x000789A6558 MnpDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C7A698 +ProtectUefiImageCommon - 0x78C7A7C0 + - 0x00000000789A6000 - 0x000000000000BBE0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 789B1068 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 789B1098 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 789B10B0 +Loading driver 529D3F93-E8E9-4E73-B1E1-BDF6A9D50113 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C79040 +Loading driver at 0x000789B7000 EntryPoint=0x000789B7558 ArpDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C79F18 +ProtectUefiImageCommon - 0x78C79040 + - 0x00000000789B7000 - 0x0000000000006E00 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 789BD6F8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 789BD740 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 789BD728 +Loading driver 94734718-0BBC-47FB-96A5-EE7A5AE6A2AD +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C799C0 +Loading driver at 0x0007898C000 EntryPoint=0x0007898C558 Dhcp4Dxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C79398 +ProtectUefiImageCommon - 0x78C799C0 + - 0x000000007898C000 - 0x000000000000C120 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 789969D8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78996A30 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78996A18 +Loading driver 9FB1A1F3-3B71-4324-B39A-745CBB015FFF +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C78040 +Loading driver at 0x00078960000 EntryPoint=0x00078960578 Ip4Dxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C78E98 +ProtectUefiImageCommon - 0x78C78040 + - 0x0000000078960000 - 0x0000000000015900 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78974330 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 789743A0 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 789743B8 +Loading driver 6D6963AB-906D-4A65-A7CA-BD40E5D6AF2B +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C784C0 +Loading driver at 0x0007899B000 EntryPoint=0x0007899B558 Udp4Dxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C77F18 +ProtectUefiImageCommon - 0x78C784C0 + - 0x000000007899B000 - 0x000000000000A3E0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 789A4938 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 789A4980 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 789A4968 +Loading driver DC3641B8-2FA8-4ED3-BC1F-F9962A03454B +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C77BC0 +Loading driver at 0x00078981000 EntryPoint=0x00078981558 Mtftp4Dxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C77A98 +ProtectUefiImageCommon - 0x78C77BC0 + - 0x0000000078981000 - 0x000000000000A620 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 7898AB78 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 7898ABC0 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 7898ABA8 +Loading driver 95E3669D-34BE-4775-A651-7EA41B69D89E +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C772C0 +Loading driver at 0x00078946000 EntryPoint=0x00078946558 Dhcp6Dxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C77098 +ProtectUefiImageCommon - 0x78C772C0 + - 0x0000000078946000 - 0x000000000000C5A0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78951998 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 789519E0 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 789519C8 +Loading driver 5BEDB5CC-D830-4EB2-8742-2D4CC9B54F2C +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C760C0 +Loading driver at 0x00078908000 EntryPoint=0x00078908578 Ip6Dxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C76918 +ProtectUefiImageCommon - 0x78C760C0 + - 0x0000000078908000 - 0x000000000001E080 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78924350 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 789243E0 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 789243C8 +Loading driver D912C7BC-F098-4367-92BA-E911083C7B0E +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C76440 +Loading driver at 0x00078976000 EntryPoint=0x00078976558 Udp6Dxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C5CE98 +ProtectUefiImageCommon - 0x78C76440 + - 0x0000000078976000 - 0x000000000000A2C0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 7897F7F8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 7897F828 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 7897F840 +Loading driver 99F03B99-98D8-49DD-A8D3-3219D0FFE41E +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C5C7C0 +Loading driver at 0x00078955000 EntryPoint=0x00078955558 Mtftp6Dxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C5C698 +ProtectUefiImageCommon - 0x78C5C7C0 + - 0x0000000078955000 - 0x000000000000ADC0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 7895F2C8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 7895F310 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 7895F2F8 +Loading driver 1A7E4468-2F55-4A56-903C-01265EB7622B +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C5B040 +Loading driver at 0x000788F4000 EntryPoint=0x000788F4558 TcpDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C5BF18 +ProtectUefiImageCommon - 0x78C5B040 + - 0x00000000788F4000 - 0x0000000000013C00 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78906B00 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78906B58 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78906B70 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 789069B8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 78906B58 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 78906B70 +Loading driver B95E9FDA-26DE-48D2-8807-1F9107AC5E3A +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C5B5C0 +Loading driver at 0x000788E1000 EntryPoint=0x000788E1558 UefiPxeBcDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C5C598 +ProtectUefiImageCommon - 0x78C5B5C0 + - 0x00000000788E1000 - 0x0000000000012900 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 788F2908 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 788F29D8 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 788F29C0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 788F28D8 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 788F29D8 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 788F29C0 +Loading driver 22DE1691-D65D-456A-993E-A253DD1F308C +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78C5A440 +Loading driver at 0x000788CC000 EntryPoint=0x000788CF0B0 +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78C5A918 +ProtectUefiImageCommon - 0x78C5A440 + - 0x00000000788CC000 - 0x00000000000145A0 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 788CD580 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 788CD528 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 788CD510 +InstallProtocolInterface: 4D330321-025F-4AAC-90D8-5ED900173B63 788CD350 +Loading driver 7C7467E9-8BB3-4BF1-8694-6FED7D25D13E +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78A49040 +Loading driver at 0x00078826000 EntryPoint=0x0007884458C +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78A49B98 +ProtectUefiImageCommon - 0x78A49040 + - 0x0000000078826000 - 0x0000000000051460 +InstallProtocolInterface: 18A031AB-B443-4D1A-A5C0-0C09261E9F71 78828A30 +InstallProtocolInterface: 107A772C-D5E1-11D4-9A46-0090273FC14D 788287B0 +InstallProtocolInterface: 0784924F-E296-11D4-9A49-0090273FC14D 78828870 +InstallProtocolInterface: 6A7A5CFF-E8D9-4F70-BADA-75AB3025CE14 788287C8 +InstallProtocolInterface: 4D330321-025F-4AAC-90D8-5ED900173B63 78828880 +InstallProtocolInterface: 107A772B-D5E1-11D4-9A46-0090273FC14D 788285F0 +InstallProtocolInterface: 2A534210-9280-41D8-AE79-CADA01A2B127 788287E8 +InstallProtocolInterface: 5C198761-16A8-4E69-972C-89D67954F81D 788287E0 +Evaluate SMM DEPEX for FFS(D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC) + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(1A819E49-D8EE-48CB-9A9C-0AA0D2810A38) = TRUE + PUSH GUID(E287D20B-D897-4E1E-A5D9-977763936A04) = TRUE + PUSH GUID(843DC720-AB1E-42CB-9357-8A0078F3561B) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + PUSH GUID(FFE06BDD-6107-46A6-7BB2-5A9C7EC5275C) = TRUE + PUSH GUID(EB97088E-CFDF-49C6-BE4B-D906A5B20E86) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = TRUE +Evaluate SMM DEPEX for FFS(ACAEAA7A-C039-4424-88DA-F42212EA0E55) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(3920405B-C897-44DA-88F3-4C498A6FF736) = TRUE + PUSH GUID(D31F0400-7D16-4316-BF88-6065883B402B) = FALSE + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + END + RESULT = FALSE +Evaluate SMM DEPEX for FFS(99EC6206-AA45-4CAE-B630-866755241C8A) + PUSH GUID(5BAB88BA-E0E2-4674-B6AD-B812F6881CD6) = TRUE + PUSH GUID(2F707EBB-4A1A-11D4-9A38-0090273FC14D) = TRUE + PUSH GUID(AD61F191-AE5F-4C0E-B9FA-E869D288C64F) = TRUE + PUSH GUID(074E1E48-8132-47A1-8C2C-3F14AD9A66DC) = TRUE + PUSH GUID(220E73B6-6BDB-4413-8405-B974B108619A) = TRUE + PUSH GUID(EF9FC172-A1B2-4693-B327-6D32FC416042) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + AND + AND + AND + END + RESULT = TRUE +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78A49318 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E7EC0 +Loading SMM driver at 0x0007B525000 EntryPoint=0x0007B526270 PchInitSmm.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Enter +SmmLockBoxSmmLib SmmLockBoxContext - already installed +SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Exit +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +mSmmMemLibInternalMaximumSupportAddress = 0xFFFFFFFFF +PchInitSmmEntryPoint() Start +InitializePchDevice() smm Start +InitializePchDevice() SMM End +PchInitSmmEntryPoint() End +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78A48018 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E62C0 +Loading SMM driver at 0x0007B512000 EntryPoint=0x0007B513270 GraphicDxeInitSmm.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Enter +SmmLockBoxSmmLib SmmLockBoxContext - already installed +SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Exit +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +mSmmMemLibInternalMaximumSupportAddress = 0xFFFFFFFFF +mSmmIoLibInternalMaximumSupportMemAddress = 0xFFFFFFFFF +GraphicsDxeInit SMM - 1 +GraphicsDxeInit - SMM - Allocate 4MB for GTTMADDR +Evaluate SMM DEPEX for FFS(ACAEAA7A-C039-4424-88DA-F42212EA0E55) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(3920405B-C897-44DA-88F3-4C498A6FF736) = TRUE + PUSH GUID(D31F0400-7D16-4316-BF88-6065883B402B) = FALSE + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + END + RESULT = FALSE +Loading driver 1D000AE9-756B-4937-B736-1F3D96A5A8F0 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78A48140 +Loading driver at 0x0007893E000 EntryPoint=0x0007893E3F0 Dptf.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78A48898 +ProtectUefiImageCommon - 0x78A48140 + - 0x000000007893E000 - 0x00000000000071C0 +DptfDriverEntry beg=0 end=293 offset=659 +DPTF Setup options are invalid. Restoring defaults Dumping DPTF settings in dptf driver... +DPTFEnabled = 1 +CpuParticipantCriticalTemperature = 90 +CpuParticipantPassiveTemperature = 85 +GenParticipant0CriticalTemperature = 70 +GenParticipant0PassiveTemperature = 60 +GenParticipant1CriticalTemperature = 75 +GenParticipant1PassiveTemperature = 55 +GenParticipant2CriticalTemperature = 70 +GenParticipant2PassiveTemperature = 60 +GenParticipant3CriticalTemperature = 75 +GenParticipant3PassiveTemperature = 50 +GenParticipant4CriticalTemperature = 75 +GenParticipant4PassiveTemperature = 50 +ClpmSetting = 3 +SuperDebug = 0 +LPOEnable = 1 +LPOStartPState = 1 +LPOStepSize = 25 +LPOPowerControlSetting = 1 +LPOPerformanceControlSetting = 1 +bDppmEnabled = 1 +SdpProfile = 0 +Loading driver DE23ACEE-CF55-4FB6-AA77-984AB53DE823 +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78A483C0 +Loading driver at 0x000787FA000 EntryPoint=0x000787FA3F0 PchInitDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78A37018 +ProtectUefiImageCommon - 0x78A483C0 + - 0x00000000787FA000 - 0x000000000002B080 +PchInitEntryPoint() Start +PCH Base Addresses: +------------------- + RCBA 0xFED1C000 + PmcBase 0xFED03000 + IoBase 0xFED0C000 + IlbBase 0xFED08000 + SpiBase 0xFED01000 + MphyBase 0xFEF00000 + AcpiBase 0x400 + GpioBase 0x500 +------------------- +InitializePchDevice() Start +ConfigureMiscPm() Start +ConfigureMiscPm() End +ConfigureAdditionalPm() PchPlatformPolicy->EhciPllCfgEnable = 0x1 +ConfigureAdditionalPm() R_IOSF_SPXB_CH1CTRL = 0x1 +ConfigureAdditionalPm() R_IOSF_SPXB_PORTCTL0 = 0x1 +ConfigureAdditionalPm() R_IOSF_SPXB_PORTCTL1 = 0x2 +ConfigureAdditionalPm() R_IOSF_SPXB_PORTCTL2 = 0x0 +ConfigureAdditionalPm() R_IOSF_SPXB_PMCTL = 0x9E +ConfigureAdditionalPm() EhciPciMmBase = 0xE00E8000 +ConfigureAdditionalPm() R_PCH_EHCI_AFEMCTLTM = 0x0 +ConfigureAdditionalPm() R_PCH_EHCI_PWR_CNTL_STS = 0x8 +ConfigureAdditionalPm() R_PCH_EHCI_CMD_STS = 0x2900400 +ConfigureAdditionalPm() R_PCH_EHCI_LEGEXT_CS = 0x0 +ConfigureMiscItems() Start +ConfigureMiscItems() End +ConfigureAzalia() Start +MCRX = 0 +MDR = C0 +MCR = 70460F0 +MCRX = 0 +MDR = 0 +MCR = 70460F0 +SDI0 has no Azalia device. +SDI1 has no Azalia device. +Detected Azalia Codec with verb table, VendorID = 0x80862882 on SDI2, revision = 0x0. +SDI3 has no Azalia device. +ConfigureAzalia() End +AzaliaEnable = 1 +ConfigureOtg() Start +Putting USB OTG into D3 Hot State. +ConfigureOtg() End +ConfigureUsb() Start +CommonUsbInit() - Start +stepping:0x8, boardid:0xB0 Fabid:0x1 +B2 or B2+ SOC on BayleyBay RVP +USB2_PHY USB2_COMPBG:0x4700 +USB2PHY reg(0x4100): 0x49A09 +USB2PHY reg(0x4122): 0x300401D +USB2PHY reg(0x4200): 0x49A09 +USB2PHY reg(0x4222): 0x300401D +USB2PHY reg(0x4300): 0x49209 +USB2PHY reg(0x4322): 0x1004015 +USB2PHY reg(0x4400): 0x49A09 +USB2PHY reg(0x4422): 0x300401D +CCU DIV_CTRL value ->0x3A08, cr_ush_clk_sel bit is 0x0 +stepping:0x8, boardid:0xB0 Fabid:0x1 +B2 or B2+ SOC on BayleyBay RVP +USB2_PHY USB2_COMPBG:0x4700 +USB2PHY reg(0x4100): 0x49A09 +USB2PHY reg(0x4122): 0x300401D +USB2PHY reg(0x4200): 0x49A09 +USB2PHY reg(0x4222): 0x300401D +USB2PHY reg(0x4300): 0x49209 +USB2PHY reg(0x4322): 0x1004015 +USB2PHY reg(0x4400): 0x49A09 +USB2PHY reg(0x4422): 0x300401D +set Late FID Check Disable:0x501037F +UsbXhciLpmSupport enabled-->XhciM mioBase:0x-2147418112 +CDN_PHY R_PCH_CDN_PLL_CONTROL:0x53 +CDN_PHY R_PCH_CDN_VCO_START_CALIBRATION_START_POINT:0xA +Ccdrlf_configuration:0x1D46018B +ree_peaking_amp_configuration_and_diagnostic :0x1FF +ree_offset_correction_configuration_and_diagnostics:0x0 +ree_vga_gain_configuration_and_diagnostics.:0x2F +ree_dac_control.:0x249F0006 +CDN_PHY R_PCH_CDN_U1_POWER_STATE_DEFINITION:0x1BCF +Putting EHCI into D3 Hot State. +CommonUsbInit() - End +ConfigureUsb() End +PchInitRootPorts() Start +PCHS3: S3ParameterRootPortDownstream.RootPortBus = 0x0 +PCHS3: S3ParameterRootPortDownstream.RootPortDevice = 0x1C +PCHS3: S3ParameterRootPortDownstream.RootPortFunc = 0x0 +PCHS3: S3ParameterRootPortDownstream.TempBusNumberMin = 0x5 +PCHS3: S3ParameterRootPortDownstream.TempBusNumberMax = 0x7 +PCHS3: S3ParameterRootPortDownstream.RootPortBus = 0x0 +PCHS3: S3ParameterRootPortDownstream.RootPortDevice = 0x1C +PCHS3: S3ParameterRootPortDownstream.RootPortFunc = 0x2 +PCHS3: S3ParameterRootPortDownstream.TempBusNumberMin = 0x5 +PCHS3: S3ParameterRootPortDownstream.TempBusNumberMax = 0x7 + Root Port 3 device enabled. RpEnableMask: 0xD +PCHS3: S3ParameterRootPortDownstream.RootPortBus = 0x0 +PCHS3: S3ParameterRootPortDownstream.RootPortDevice = 0x1C +PCHS3: S3ParameterRootPortDownstream.RootPortFunc = 0x3 +PCHS3: S3ParameterRootPortDownstream.TempBusNumberMin = 0x5 +PCHS3: S3ParameterRootPortDownstream.TempBusNumberMax = 0x7 +PchInitRootPorts() End +ConfigureSata() Start +ConfigureSata() End +ConfigureLpe() Start +LPE Allocate Audio Memory success at 0x20000000 +Putting LPE Audio into D3 Hot State. +ConfigureLpe() End +ConfigureLpss() Start +Putting LPSS2 I2C 0 into D3 Hot State. +LpssPciMmBase:------------------E00C1000. +Putting LPSS2 I2C 1 into D3 Hot State. +Putting LPSS2 I2C 2 into D3 Hot State. +Putting LPSS2 I2C 3 into D3 Hot State. +Putting LPSS2 I2C 4 into D3 Hot State. +ConfigureLpss() End +ConfigureScc() Start +eMMC DLL Settings for BBAY. +ConfigureDLLSettingForEMMC45: eMMC DLL Settings for BayleyBay . +Putting SCC eMMC 4.41 into D3 Hot State. +Disable Transfer Suspend/Resume support for SOC B0 and later! +ConfigureSdCardCap: Overwride Capability Register +ConfigureSdCardCap: New Capability Reg = 0x80000000-76864B2 +Enable 2ms_card_stable feature for B1 and later SOC! +ConfigureEMMC45: Overwride Capability Register +ConfigureEMMC45: set retume timer value 0x8 +ConfigureEMMC45: New Capability Reg = 0x80000807-446CC801 +Register the call back for eMMC singalling configuration. +ConfigureScc() End +ConfigureClockGating() Start +ConfigureClockGating() End +ConfigureIoApic() Start +ConfigureIoApic() End +ProgramSvidSid() Start +Writing SVID/SID for B0/D31/F3 +Writing SVID/SID for B0/D31/F0 +Writing SVID/SID for B0/D30/F5 +Writing SVID/SID for B0/D30/F4 +Writing SVID/SID for B0/D30/F3 +Writing SVID/SID for B0/D30/F2 +Writing SVID/SID for B0/D30/F1 +Writing SVID/SID for B0/D30/F0 +Writing SVID/SID for B0/D28/F3 +Writing SVID/SID for B0/D28/F2 +Writing SVID/SID for B0/D28/F0 +Writing SVID/SID for B0/D27/F0 +Writing SVID/SID for B0/D26/F0 +Writing SVID/SID for B0/D2/F0 +Writing SVID/SID for B0/D24/F7 +Writing SVID/SID for B0/D24/F6 +Writing SVID/SID for B0/D24/F0 +Writing SVID/SID for B0/D23/F0 +Writing SVID/SID for B0/D20/F0 +Writing SVID/SID for B0/D19/F0 +Writing SVID/SID for B0/D18/F0 +Writing SVID/SID for B0/D17/F0 +ProgramSvidSid() End +PchInitBeforeBoot() Start +PciERWORegInit() Start +PciERWORegInit() End +Endpoint Device 0 Capability ASPM: 3 +Calculate Endpoint Device 0 Aspm Value: 2 +Program Endpoint Device 0 Aspm Value: 2 +LockPciDevCap() BusNumber = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x0,Func = 0x0 +LockPciDevCap() PciEAddressBase = 0xE0000000 +LockPciDevCap() StatusReg = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x2,Func = 0x0 +LockPciDevCap() PciEAddressBase = 0xE0010000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0xD0 +LockPciDevCap() While CAPBILITY = 0x9001 +LockPciDevCap() While CapId = 0x90 +LockPciDevCap() While CAPBILITY = 0xB005 +LockPciDevCap() While CapId = 0xB0 +LockPciDevCap() While CAPBILITY = 0x9 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x11,Func = 0x0 +LockPciDevCap() PciEAddressBase = 0xE0088000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x12,Func = 0x0 +LockPciDevCap() PciEAddressBase = 0xE0090000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x13,Func = 0x0 +LockPciDevCap() PciEAddressBase = 0xE0098000 +LockPciDevCap() StatusReg = 0x2B0 +LockPciDevCap() StatusReg = 0x2B0 +LockPciDevCap() CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x7005 +LockPciDevCap() While CapId = 0x70 +LockPciDevCap() While CAPBILITY = 0xA801 +LockPciDevCap() While CapId = 0xA8 +LockPciDevCap() While CAPBILITY = 0x12 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x14,Func = 0x0 +LockPciDevCap() PciEAddressBase = 0xE00A0000 +LockPciDevCap() StatusReg = 0x290 +LockPciDevCap() StatusReg = 0x290 +LockPciDevCap() CapId = 0x70 +LockPciDevCap() While CAPBILITY = 0x8001 +LockPciDevCap() While CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x5 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x17,Func = 0x0 +LockPciDevCap() PciEAddressBase = 0xE00B8000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x18,Func = 0x0 +LockPciDevCap() PciEAddressBase = 0xE00C0000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x18,Func = 0x6 +LockPciDevCap() PciEAddressBase = 0xE00C6000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x1A,Func = 0x0 +LockPciDevCap() PciEAddressBase = 0xE00D0000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0xA001 +LockPciDevCap() While CapId = 0xA0 +LockPciDevCap() While CAPBILITY = 0x5 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x1B,Func = 0x0 +LockPciDevCap() PciEAddressBase = 0xE00D8000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x50 +LockPciDevCap() While CAPBILITY = 0x6001 +LockPciDevCap() While CapId = 0x60 +LockPciDevCap() While CAPBILITY = 0x5 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x1C,Func = 0x0 +LockPciDevCap() PciEAddressBase = 0xE00E0000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x40 +LockPciDevCap() While CAPBILITY = 0x8010 +LockPciDevCap() While CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x9005 +LockPciDevCap() While CapId = 0x90 +LockPciDevCap() While CAPBILITY = 0xA00D +LockPciDevCap() While CapId = 0xA0 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x1C,Func = 0x2 +LockPciDevCap() PciEAddressBase = 0xE00E2000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x40 +LockPciDevCap() While CAPBILITY = 0x8010 +LockPciDevCap() While CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x9005 +LockPciDevCap() While CapId = 0x90 +LockPciDevCap() While CAPBILITY = 0xA00D +LockPciDevCap() While CapId = 0xA0 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x1C,Func = 0x3 +LockPciDevCap() PciEAddressBase = 0xE00E3000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x40 +LockPciDevCap() While CAPBILITY = 0x8010 +LockPciDevCap() While CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x9005 +LockPciDevCap() While CapId = 0x90 +LockPciDevCap() While CAPBILITY = 0xA00D +LockPciDevCap() While CapId = 0xA0 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x1E,Func = 0x0 +LockPciDevCap() PciEAddressBase = 0xE00F0000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x1E,Func = 0x1 +LockPciDevCap() PciEAddressBase = 0xE00F1000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x1E,Func = 0x2 +LockPciDevCap() PciEAddressBase = 0xE00F2000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x1E,Func = 0x3 +LockPciDevCap() PciEAddressBase = 0xE00F3000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x1E,Func = 0x4 +LockPciDevCap() PciEAddressBase = 0xE00F4000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +LockPciDevCap() Bus = 0x0,Dev = 0x1E,Func = 0x5 +LockPciDevCap() PciEAddressBase = 0xE00F5000 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() StatusReg = 0x10 +LockPciDevCap() CapId = 0x80 +LockPciDevCap() While CAPBILITY = 0x1 +LockPciDevCap() While CapId = 0x0 +PchInitBeforeBoot() End +InitializePchDevice() End +InstallProtocolInterface: D31F0400-7D16-4316-BF88-6065883B402B 78A37718 +PchInitEntryPoint() End +Loading driver 93C81A74-B648-4F7F-925E-E4A0CDCC776D +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78A37240 +Loading driver at 0x000788BE000 EntryPoint=0x000788BE3F0 VlvInitDxe.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78A37598 +ProtectUefiImageCommon - 0x78A37240 + - 0x00000000788BE000 - 0x000000000000D780 +Initializing Legacy Region +InstallProtocolInterface: 0FC9013A-0568-4BA9-9B7E-C9C390A6609B 788CAEF0 +Initializing GT PowerManagement and other GT POST related +GraphicsDxeInit - 1 +GraphicsDxeInit - 2 +GraphicsDxeInit - 3 +GraphicsDxeInit - 4 +GraphicsDxeInit - 5 +GraphicsDxeInit - 6 +GraphicsDxeInit - 7 +GraphicsDxeInit - 8 +GraphicsDxeInit - 9 +GraphicsDxeInit - a +Initializing PAVP +GraphicsDxeInit - b +Initializing GT PowerManagement +Polling allow-wake bit +Polling Render Force Wake Acknowledge Bit +Polling Media ForceWakeReq Acknowledge Bit +PcBase = 0x7FEFA000 +GraphicsDxeInit - c +GraphicsDxeInit - d +GraphicsDxeInit - f +Initializing IGD OpRegion +System BIOS ID is Intel +S0ix not Supported! +HD Audio Support! +InstallProtocolInterface: CDC5DDDF-E79D-41EC-A9B0-6565490DB9D3 788CAF28 +GlobalNvsArea->Area->BmBound = 0x80000000 +Evaluate SMM DEPEX for FFS(ACAEAA7A-C039-4424-88DA-F42212EA0E55) + PUSH GUID(F4CCBFB7-F6E0-47FD-9DD4-10A8F150C191) = TRUE + PUSH GUID(3920405B-C897-44DA-88F3-4C498A6FF736) = TRUE + PUSH GUID(D31F0400-7D16-4316-BF88-6065883B402B) = TRUE + PUSH GUID(4B0165A9-61D6-4E23-A0B5-3EC79C2E30D5) = TRUE + PUSH GUID(13A3F0F6-264A-3EF0-F2E0-DEC512342F34) = TRUE + PUSH GUID(C2702B74-800C-4131-8746-8FB5B89CE4AC) = TRUE + AND + AND + AND + AND + AND + END + RESULT = TRUE +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 78A36698 +SmmInstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7B7E78C0 +Loading SMM driver at 0x0007B4FE000 EntryPoint=0x0007B4FF240 PchPcieSmm.efi +SMRAM Map Buffer too small +SMRAM Map Buffer installed complet +SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Enter +SmmLockBoxSmmLib SmmLockBoxContext - already installed +SmmLockBoxSmmLib SmmLockBoxSmmConstructor - Exit +InitializePchPcieSmm() Start +InitializePchPcieSmm() End +[Bds] Entry... +FvbProtocolWrite: Lba: 0x0 Offset: 0x2564 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2566 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x25A0 NumBytes: 0x16, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2566 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x25B8 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x25BA NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x25F4 NumBytes: 0x5C, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x25BA NumBytes: 0x1, Buffer: 0x7B6DF01A +[BdsDxe] Locate Variable Policy protocol - Success +FvbProtocolWrite: Lba: 0x0 Offset: 0x2650 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2652 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x268C NumBytes: 0x1D, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2652 NumBytes: 0x1, Buffer: 0x7B6DF01A +Variable Driver Auto Update Lang, Lang:eng, PlatformLang:en Status: Success +FvbProtocolWrite: Lba: 0x0 Offset: 0x26AC NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x26AE NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x26E8 NumBytes: 0xE, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x26AE NumBytes: 0x1, Buffer: 0x7B6DF01A +!!! DEPRECATED INTERFACE !!! VariableLockRequestToLock() will go away soon! +!!! DEPRECATED INTERFACE !!! Please move to use Variable Policy! +!!! DEPRECATED INTERFACE !!! Variable: 8BE4DF61-93CA-11D2-AA0D-00E098032B8C PlatformRecovery0000 +PlatformBootManagerBeforeConsole +PCI Bus First Scanning +PciBus: Discovered PCI @ [00|00|00] + +PciBus: Discovered PCI @ [00|02|00] + BAR[0]: Type = Mem32; Alignment = 0x3FFFFF; Length = 0x400000; Offset = 0x10 + BAR[2]: Type = PMem32; Alignment = 0xFFFFFFF; Length = 0x10000000; Offset = 0x18 + BAR[4]: Type = Io16; Alignment = 0x7; Length = 0x8; Offset = 0x20 + +PciBus: Discovered PCI @ [00|11|00] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|12|00] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|13|00] + BAR[0]: Type = Io16; Alignment = 0x7; Length = 0x8; Offset = 0x10 + BAR[1]: Type = Io16; Alignment = 0x3; Length = 0x4; Offset = 0x14 + BAR[2]: Type = Io16; Alignment = 0x7; Length = 0x8; Offset = 0x18 + BAR[3]: Type = Io16; Alignment = 0x3; Length = 0x4; Offset = 0x1C + BAR[4]: Type = Io16; Alignment = 0x1F; Length = 0x20; Offset = 0x20 + BAR[5]: Type = Mem32; Alignment = 0xFFF; Length = 0x800; Offset = 0x24 + +PciBus: Discovered PCI @ [00|14|00] + BAR[0]: Type = Mem64; Alignment = 0xFFFF; Length = 0x10000; Offset = 0x10 + +PciBus: Discovered PCI @ [00|17|00] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|18|00] + BAR[0]: Type = Mem32; Alignment = 0x3FFF; Length = 0x4000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|18|06] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|18|07] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1A|00] + BAR[0]: Type = Mem32; Alignment = 0xFFFFF; Length = 0x100000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFFFF; Length = 0x100000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1B|00] + BAR[0]: Type = Mem64; Alignment = 0x3FFF; Length = 0x4000; Offset = 0x10 + +PciBus: Discovered PPB @ [00|1C|00] + +PciBus: Discovered PPB @ [00|1C|02] + +PciBus: Discovered PCI @ [02|00|00] + BAR[0]: Type = Mem32; Alignment = 0x7FFFF; Length = 0x80000; Offset = 0x10 + BAR[2]: Type = Io32; Alignment = 0x1F; Length = 0x20; Offset = 0x18 + BAR[3]: Type = Mem32; Alignment = 0x3FFF; Length = 0x4000; Offset = 0x1C + +PciBus: Discovered PPB @ [00|1C|03] + +PciBus: Discovered PCI @ [00|1E|00] + BAR[0]: Type = Mem32; Alignment = 0x3FFF; Length = 0x4000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1E|01] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1E|02] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1E|03] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1E|04] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1E|05] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1F|00] + +PciBus: Discovered PCI @ [00|1F|03] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x20; Offset = 0x10 + BAR[4]: Type = Io16; Alignment = 0x1F; Length = 0x20; Offset = 0x20 + +PciBus: Discovered PCI @ [00|00|00] + +PciBus: Discovered PCI @ [00|02|00] + BAR[0]: Type = Mem32; Alignment = 0x3FFFFF; Length = 0x400000; Offset = 0x10 + BAR[2]: Type = PMem32; Alignment = 0xFFFFFFF; Length = 0x10000000; Offset = 0x18 + BAR[4]: Type = Io16; Alignment = 0x7; Length = 0x8; Offset = 0x20 + +PciBus: Discovered PCI @ [00|11|00] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|12|00] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|13|00] + BAR[0]: Type = Io16; Alignment = 0x7; Length = 0x8; Offset = 0x10 + BAR[1]: Type = Io16; Alignment = 0x3; Length = 0x4; Offset = 0x14 + BAR[2]: Type = Io16; Alignment = 0x7; Length = 0x8; Offset = 0x18 + BAR[3]: Type = Io16; Alignment = 0x3; Length = 0x4; Offset = 0x1C + BAR[4]: Type = Io16; Alignment = 0x1F; Length = 0x20; Offset = 0x20 + BAR[5]: Type = Mem32; Alignment = 0xFFF; Length = 0x800; Offset = 0x24 + +PciBus: Discovered PCI @ [00|14|00] + BAR[0]: Type = Mem64; Alignment = 0xFFFF; Length = 0x10000; Offset = 0x10 + +PciBus: Discovered PCI @ [00|17|00] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|18|00] + BAR[0]: Type = Mem32; Alignment = 0x3FFF; Length = 0x4000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|18|06] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|18|07] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1A|00] + BAR[0]: Type = Mem32; Alignment = 0xFFFFF; Length = 0x100000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFFFF; Length = 0x100000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1B|00] + BAR[0]: Type = Mem64; Alignment = 0x3FFF; Length = 0x4000; Offset = 0x10 + +PciBus: Discovered PPB @ [00|1C|00] + +PciBus: Discovered PPB @ [00|1C|02] + +PciBus: Discovered PCI @ [02|00|00] + BAR[0]: Type = Mem32; Alignment = 0x7FFFF; Length = 0x80000; Offset = 0x10 + BAR[2]: Type = Io32; Alignment = 0x1F; Length = 0x20; Offset = 0x18 + BAR[3]: Type = Mem32; Alignment = 0x3FFF; Length = 0x4000; Offset = 0x1C + +PciBus: Discovered PPB @ [00|1C|03] + +PciBus: Discovered PCI @ [00|1E|00] + BAR[0]: Type = Mem32; Alignment = 0x3FFF; Length = 0x4000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1E|01] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1E|02] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1E|03] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1E|04] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1E|05] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x10 + BAR[1]: Type = Mem32; Alignment = 0xFFF; Length = 0x1000; Offset = 0x14 + +PciBus: Discovered PCI @ [00|1F|00] + +PciBus: Discovered PCI @ [00|1F|03] + BAR[0]: Type = Mem32; Alignment = 0xFFF; Length = 0x20; Offset = 0x10 + BAR[4]: Type = Io16; Alignment = 0x1F; Length = 0x20; Offset = 0x20 + +PciBus: HostBridge->SubmitResources() - Success +PciBus: HostBridge->NotifyPhase(AllocateResources) - Success +Process Option ROM: BAR Base/Length = 0/0 +PciBus: Resource Map for Root Bridge PciRoot(0x0) +Type = Io16; Base = 0x1000; Length = 0x2000; Alignment = 0xFFF + Base = 0x1000; Length = 0x1000; Alignment = 0xFFF; Owner = PPB [00|1C|02:**] + Base = 0x2000; Length = 0x20; Alignment = 0x1F; Owner = PCI [00|1F|03:20] + Base = 0x2020; Length = 0x20; Alignment = 0x1F; Owner = PCI [00|13|00:20] + Base = 0x2040; Length = 0x8; Alignment = 0x7; Owner = PCI [00|13|00:18] + Base = 0x2048; Length = 0x8; Alignment = 0x7; Owner = PCI [00|13|00:10] + Base = 0x2050; Length = 0x8; Alignment = 0x7; Owner = PCI [00|02|00:20] + Base = 0x2058; Length = 0x4; Alignment = 0x3; Owner = PCI [00|13|00:1C] + Base = 0x205C; Length = 0x4; Alignment = 0x3; Owner = PCI [00|13|00:14] +Type = Mem32; Base = 0x80000000; Length = 0x10800000; Alignment = 0xFFFFFFF + Base = 0x80000000; Length = 0x10000000; Alignment = 0xFFFFFFF; Owner = PCI [00|02|00:18]; Type = PMem32 + Base = 0x90000000; Length = 0x400000; Alignment = 0x3FFFFF; Owner = PCI [00|02|00:10] + Base = 0x90400000; Length = 0x100000; Alignment = 0xFFFFF; Owner = PPB [00|1C|02:**] + Base = 0x90500000; Length = 0x100000; Alignment = 0xFFFFF; Owner = PCI [00|1A|00:14] + Base = 0x90600000; Length = 0x100000; Alignment = 0xFFFFF; Owner = PCI [00|1A|00:10] + Base = 0x90700000; Length = 0x10000; Alignment = 0xFFFF; Owner = PCI [00|14|00:10] + Base = 0x90710000; Length = 0x4000; Alignment = 0x3FFF; Owner = PCI [00|1B|00:10] + Base = 0x90714000; Length = 0x4000; Alignment = 0x3FFF; Owner = PCI [00|1E|00:10] + Base = 0x90718000; Length = 0x4000; Alignment = 0x3FFF; Owner = PCI [00|18|00:10] + Base = 0x9071C000; Length = 0x20; Alignment = 0xFFF; Owner = PCI [00|1F|03:10] + Base = 0x9071D000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|1E|05:14] + Base = 0x9071E000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|1E|05:10] + Base = 0x9071F000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|1E|04:14] + Base = 0x90720000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|1E|04:10] + Base = 0x90721000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|1E|03:14] + Base = 0x90722000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|1E|03:10] + Base = 0x90723000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|1E|02:14] + Base = 0x90724000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|1E|02:10] + Base = 0x90725000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|1E|01:14] + Base = 0x90726000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|1E|01:10] + Base = 0x90727000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|1E|00:14] + Base = 0x90728000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|18|07:14] + Base = 0x90729000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|18|07:10] + Base = 0x9072A000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|18|06:14] + Base = 0x9072B000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|18|06:10] + Base = 0x9072C000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|18|00:14] + Base = 0x9072D000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|17|00:14] + Base = 0x9072E000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|17|00:10] + Base = 0x9072F000; Length = 0x800; Alignment = 0xFFF; Owner = PCI [00|13|00:24] + Base = 0x90730000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|12|00:14] + Base = 0x90731000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|12|00:10] + Base = 0x90732000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|11|00:14] + Base = 0x90733000; Length = 0x1000; Alignment = 0xFFF; Owner = PCI [00|11|00:10] + +PciBus: Resource Map for Bridge [00|1C|00] + +PciBus: Resource Map for Bridge [00|1C|02] +Type = Io16; Base = 0x1000; Length = 0x1000; Alignment = 0xFFF + Base = 0x1000; Length = 0x20; Alignment = 0x1F; Owner = PCI [02|00|00:18] +Type = Mem32; Base = 0x90400000; Length = 0x100000; Alignment = 0xFFFFF + Base = 0x90400000; Length = 0x80000; Alignment = 0x7FFFF; Owner = PCI [02|00|00:10] + Base = 0x90480000; Length = 0x4000; Alignment = 0x3FFF; Owner = PCI [02|00|00:1C] + +PciBus: Resource Map for Bridge [00|1C|03] + +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A35898 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A09028 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A35818 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A09428 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A09E98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A09828 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A09F18 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A08028 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A09F98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A08428 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A08E98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A08828 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A08F18 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A07028 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A08F98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A07428 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A07E98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A07828 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A07F18 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A06028 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A07F98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A06428 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A06E98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A06828 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A06F18 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A05028 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A06F98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A05428 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A05E98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A05828 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A05F18 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A04028 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A05F98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A04428 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A04E98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A04828 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A04F18 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A03028 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A04F98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A03428 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A03E98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A03828 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A03F18 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A02028 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A03F98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A02428 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78A02E98 +InstallProtocolInterface: 4CF5B200-68B8-4CA5-9EEC-B23E3F50029A 78A02828 +InstallProtocolInterface: 30CFE3E7-3DE1-4586-BE20-DEABA1B3B793 0 +PlatformBootManagerBeforeConsole: BootMode = 0 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 789E7698 +InstallProtocolInterface: 39487C79-236D-4666-87E5-09547CAAE1BC 789E7518 +InstallProtocolInterface: 1C0C34F6-D380-41FA-A049-8AD06C1A66AA 789E7550 +InstallProtocolInterface: 9042A9DE-23DC-4A38-96FB-7ADED080516A 789E7530 +InstallProtocolInterface: BD8C1056-9F36-44EC-92A8-A6337F817986 789E7560 +GraphicsConsole video resolution 800 x 600 +Graphics - Mode 0, Column = 80, Row = 25 +Graphics - Mode 1, Column = 0, Row = 0 +Graphics - Mode 2, Column = 100, Row = 31 +Graphics Console Started, Mode: 2 +InstallProtocolInterface: 387477C2-69C7-11D2-8E39-00A0C969723B 789B60B0 +FvbProtocolWrite: Lba: 0x0 Offset: 0x26F8 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x26FA NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2734 NumBytes: 0x2C, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x26FA NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2760 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2762 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x279C NumBytes: 0x1B, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2762 NumBytes: 0x1, Buffer: 0x7B6DF01A +[EnumIsaSerial] +FvbProtocolWrite: Lba: 0x0 Offset: 0x2762 NumBytes: 0x1, Buffer: 0x7B657720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x27B8 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x27BA NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x27F4 NumBytes: 0x64, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x27BA NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2762 NumBytes: 0x1, Buffer: 0x7B657720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x26FA NumBytes: 0x1, Buffer: 0x7B65D720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2858 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x285A NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2894 NumBytes: 0x75, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x285A NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x26FA NumBytes: 0x1, Buffer: 0x7B65D720 +[EnumUsbKeyboard] +InstallProtocolInterface: D3B36F2C-D551-11D4-9A46-0090273FC14D 0 +InstallProtocolInterface: 9042A9DE-23DC-4A38-96FB-7ADED080516A 78A47210 +InstallProtocolInterface: 982C298B-F4FA-41CB-B838-77AA688FB839 78A471E8 +BdsCreateShellDevicePath +FvbProtocolWrite: Lba: 0x0 Offset: 0x2566 NumBytes: 0x1, Buffer: 0x7B65D720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x290C NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x290E NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2948 NumBytes: 0x18, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x290E NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2566 NumBytes: 0x1, Buffer: 0x7B65D720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2960 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2962 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x299C NumBytes: 0x74, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2962 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x290E NumBytes: 0x1, Buffer: 0x7B657720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2A10 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2A12 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2A4C NumBytes: 0x1A, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2A12 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x290E NumBytes: 0x1, Buffer: 0x7B657720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2A68 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2A6A NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2AA4 NumBytes: 0x66, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2A6A NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2B0C NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2B0E NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2B48 NumBytes: 0x1E, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2B0E NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2B68 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2B6A NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2BA4 NumBytes: 0x1E, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2B6A NumBytes: 0x1, Buffer: 0x7B6DF01A +ExitPmAuth ()- Start +FPDT: ACPI Boot Performance Table address = 0x79F79000 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2BC4 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2BC6 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2C00 NumBytes: 0x38, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2BC6 NumBytes: 0x1, Buffer: 0x7B6DF01A +VLV2: FmpDeviceLock() for system FLASH +FmpDxe(Minnow Max System Firmware Device): FmpDeviceLock() returned error. Status = Unsupported +SmmEndOfDxeHandler +SmmInstallProtocolInterface: 24E70042-D5C5-4260-8C39-0AD3AA32E93D 0 +[Variable]SMM_END_OF_DXE is signaled +Initialize variable error flag (FF) +FvbProtocolWrite: Lba: 0x0 Offset: 0x2C38 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2C3A NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2C74 NumBytes: 0x1B, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2C3A NumBytes: 0x1, Buffer: 0x7B6DF01A +AcpiS3ContextSave! +SmmLockBoxDxeLib SaveLockBox - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A358948 +SmmLockBox Command - 1 +SmmLockBoxSmmLib SaveLockBox - Enter +LockBoxGuid - DEA652B0-D587-4C54-B5B4-C682E7A0AA3D, SmramBuffer - 0x7B4F3000, Length - 0xA +SmmLockBoxSmmLib SaveLockBox - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SaveLockBox - Exit (Success) +SmmLockBoxDxeLib SetLockBoxAttributes - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A358968 +SmmLockBox Command - 4 +SmmLockBoxSmmLib SetLockBoxAttributes - Enter +SmmLockBoxSmmLib SetLockBoxAttributes - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SetLockBoxAttributes - Exit (Success) +AcpiS3ContextSave TotalPageTableSize - 0xE pages +AcpiS3Context: AcpiFacsTable is 0x79F8B000 +AcpiS3Context: IdtrProfile is 0x79F77000 +AcpiS3Context: S3NvsPageTableAddress is 0x79F4A000 +AcpiS3Context: S3DebugBufferAddress is 0x79F41000 +AcpiS3Context: BootScriptStackBase is 0x79F42000 +AcpiS3Context: BootScriptStackSize is 0x 8000 +SmmLockBoxDxeLib SaveLockBox - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A358948 +SmmLockBox Command - 1 +SmmLockBoxSmmLib SaveLockBox - Enter +LockBoxGuid - AF9FFD67-EC10-488A-9DFC-6CBF5EE22C2E, SmramBuffer - 0x7B4F2000, Length - 0x8 +SmmLockBoxSmmLib SaveLockBox - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SaveLockBox - Exit (Success) +SmmLockBoxDxeLib SaveLockBox - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A358948 +SmmLockBox Command - 1 +SmmLockBoxSmmLib SaveLockBox - Enter +LockBoxGuid - 0EF98D3A-3E33-497A-A401-77BE3EB74F38, SmramBuffer - 0x7B4F1000, Length - 0x30 +SmmLockBoxSmmLib SaveLockBox - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SaveLockBox - Exit (Success) +SmmLockBoxDxeLib SetLockBoxAttributes - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A358968 +SmmLockBox Command - 4 +SmmLockBoxSmmLib SetLockBoxAttributes - Enter +SmmLockBoxSmmLib SetLockBoxAttributes - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SetLockBoxAttributes - Exit (Success) +All EndOfDxe callbacks have returned successfully +InstallProtocolInterface: 60FF8964-E906-41D0-AFED-F241E974E08E 0 +InstallProtocolInterface: FA20568B-548B-4B2B-81EF-1BA08D4A3CEC 0 +SmmLockBoxDxeLib SaveLockBox - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A358768 +SmmLockBox Command - 1 +SmmLockBoxSmmLib SaveLockBox - Enter +LockBoxGuid - 3079818C-46D4-4A73-AEF3-E3E46CF1EEDB, SmramBuffer - 0x7B4F0000, Length - 0x8 +SmmLockBoxSmmLib SaveLockBox - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SaveLockBox - Exit (Success) +SmmLockBoxDxeLib SaveLockBox - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A358768 +SmmLockBox Command - 1 +SmmLockBoxSmmLib SaveLockBox - Enter +LockBoxGuid - 79CB58C4-AC51-442F-AFD7-98E47D2E9908, SmramBuffer - 0x7B4EF000, Length - 0x8 +SmmLockBoxSmmLib SaveLockBox - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SaveLockBox - Exit (Success) +SmmLockBoxDxeLib SetLockBoxAttributes - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A358788 +SmmLockBox Command - 4 +SmmLockBoxSmmLib SetLockBoxAttributes - Enter +SmmLockBoxSmmLib SetLockBoxAttributes - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SetLockBoxAttributes - Exit (Success) +SmmLockBoxDxeLib SaveLockBox - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A3587D8 +SmmLockBox Command - 1 +SmmLockBoxSmmLib SaveLockBox - Enter +LockBoxGuid - 9A8D3433-9FE8-42B6-870B-1E31C84EBE3B, SmramBuffer - 0x7B4E0000, Length - 0xE300 +SmmLockBoxSmmLib SaveLockBox - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SaveLockBox - Exit (Success) +SmmLockBoxDxeLib SetLockBoxAttributes - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A3587F8 +SmmLockBox Command - 4 +SmmLockBoxSmmLib SetLockBoxAttributes - Enter +SmmLockBoxSmmLib SetLockBoxAttributes - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SetLockBoxAttributes - Exit (Success) +SmmLockBoxDxeLib SaveLockBox - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A3588B8 +SmmLockBox Command - 1 +SmmLockBoxSmmLib SaveLockBox - Enter +LockBoxGuid - AEA6B965-DCF5-4311-B4B8-0F12464494D2, SmramBuffer - 0x7B4DA000, Length - 0x6000 +SmmLockBoxSmmLib SaveLockBox - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SaveLockBox - Exit (Success) +SmmLockBoxDxeLib SetLockBoxAttributes - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A3588C8 +SmmLockBox Command - 4 +SmmLockBoxSmmLib SetLockBoxAttributes - Enter +SmmLockBoxSmmLib SetLockBoxAttributes - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SetLockBoxAttributes - Exit (Success) +SmmLockBoxDxeLib SaveLockBox - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A3588B8 +SmmLockBox Command - 1 +SmmLockBoxSmmLib SaveLockBox - Enter +LockBoxGuid - 1810AB4A-2314-4DF6-81EB-67C6EC058591, SmramBuffer - 0x7B4D9000, Length - 0x8 +SmmLockBoxSmmLib SaveLockBox - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SaveLockBox - Exit (Success) +SmmLockBoxDxeLib SetLockBoxAttributes - Enter +SmmLockBox SmmLockBoxHandler Enter +SmmLockBox LockBoxParameterHeader - 7A3588C8 +SmmLockBox Command - 4 +SmmLockBoxSmmLib SetLockBoxAttributes - Enter +SmmLockBoxSmmLib SetLockBoxAttributes - Exit (Success) +SmmLockBox SmmLockBoxHandler Exit +SmmLockBoxDxeLib SetLockBoxAttributes - Exit (Success) +SmmInstallProtocolInterface: 47B7FA8C-F4BD-4AF6-8200-333086F0D2C8 0 +GetUefiMemoryMap +Patch page table start ... +Patch page table done! +MemoryAttributesTable: + Version - 0x00000001 + NumberOfEntries - 0x00000053 + DescriptorSize - 0x00000030 +Entry (0x7B4F9028) + Type - 0x6 + PhysicalStart - 0x000000007B000000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000004000 +Entry (0x7B4F9058) + Type - 0x7 + PhysicalStart - 0x000000007B001000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x00000000000004F9 + Attribute - 0x0000000000004000 +Entry (0x7B4F9088) + Type - 0x6 + PhysicalStart - 0x000000007B4FA000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000005 + Attribute - 0x0000000000004000 +Entry (0x7B4F90B8) + Type - 0x5 + PhysicalStart - 0x000000007B4FF000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x000000000000000B + Attribute - 0x0000000000020000 +Entry (0x7B4F90E8) + Type - 0x6 + PhysicalStart - 0x000000007B50A000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000006 + Attribute - 0x0000000000004000 +Entry (0x7B4F9118) + Type - 0x5 + PhysicalStart - 0x000000007B510000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9148) + Type - 0x6 + PhysicalStart - 0x000000007B511000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000002 + Attribute - 0x0000000000004000 +Entry (0x7B4F9178) + Type - 0x5 + PhysicalStart - 0x000000007B513000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x000000000000000B + Attribute - 0x0000000000020000 +Entry (0x7B4F91A8) + Type - 0x6 + PhysicalStart - 0x000000007B51E000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000006 + Attribute - 0x0000000000004000 +Entry (0x7B4F91D8) + Type - 0x5 + PhysicalStart - 0x000000007B524000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9208) + Type - 0x6 + PhysicalStart - 0x000000007B525000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000004000 +Entry (0x7B4F9238) + Type - 0x5 + PhysicalStart - 0x000000007B526000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x000000000000000D + Attribute - 0x0000000000020000 +Entry (0x7B4F9268) + Type - 0x6 + PhysicalStart - 0x000000007B533000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000007 + Attribute - 0x0000000000004000 +Entry (0x7B4F9298) + Type - 0x5 + PhysicalStart - 0x000000007B53A000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F92C8) + Type - 0x6 + PhysicalStart - 0x000000007B53B000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000004000 +Entry (0x7B4F92F8) + Type - 0x5 + PhysicalStart - 0x000000007B53C000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000006 + Attribute - 0x0000000000020000 +Entry (0x7B4F9328) + Type - 0x6 + PhysicalStart - 0x000000007B542000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000006 + Attribute - 0x0000000000004000 +Entry (0x7B4F9358) + Type - 0x5 + PhysicalStart - 0x000000007B548000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9388) + Type - 0x6 + PhysicalStart - 0x000000007B549000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000002 + Attribute - 0x0000000000004000 +Entry (0x7B4F93B8) + Type - 0x5 + PhysicalStart - 0x000000007B54B000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x000000000000000F + Attribute - 0x0000000000020000 +Entry (0x7B4F93E8) + Type - 0x6 + PhysicalStart - 0x000000007B55A000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000007 + Attribute - 0x0000000000004000 +Entry (0x7B4F9418) + Type - 0x5 + PhysicalStart - 0x000000007B561000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9448) + Type - 0x6 + PhysicalStart - 0x000000007B562000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000004000 +Entry (0x7B4F9478) + Type - 0x5 + PhysicalStart - 0x000000007B563000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000005 + Attribute - 0x0000000000020000 +Entry (0x7B4F94A8) + Type - 0x6 + PhysicalStart - 0x000000007B568000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000006 + Attribute - 0x0000000000004000 +Entry (0x7B4F94D8) + Type - 0x5 + PhysicalStart - 0x000000007B56E000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9508) + Type - 0x6 + PhysicalStart - 0x000000007B56F000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x000000000000002A + Attribute - 0x0000000000004000 +Entry (0x7B4F9538) + Type - 0x5 + PhysicalStart - 0x000000007B599000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000006 + Attribute - 0x0000000000020000 +Entry (0x7B4F9568) + Type - 0x6 + PhysicalStart - 0x000000007B59F000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000006 + Attribute - 0x0000000000004000 +Entry (0x7B4F9598) + Type - 0x5 + PhysicalStart - 0x000000007B5A5000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F95C8) + Type - 0x6 + PhysicalStart - 0x000000007B5A6000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000004000 +Entry (0x7B4F95F8) + Type - 0x5 + PhysicalStart - 0x000000007B5A7000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000003 + Attribute - 0x0000000000020000 +Entry (0x7B4F9628) + Type - 0x6 + PhysicalStart - 0x000000007B5AA000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000005 + Attribute - 0x0000000000004000 +Entry (0x7B4F9658) + Type - 0x5 + PhysicalStart - 0x000000007B5AF000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9688) + Type - 0x6 + PhysicalStart - 0x000000007B5B0000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000004000 +Entry (0x7B4F96B8) + Type - 0x5 + PhysicalStart - 0x000000007B5B1000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000005 + Attribute - 0x0000000000020000 +Entry (0x7B4F96E8) + Type - 0x6 + PhysicalStart - 0x000000007B5B6000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000006 + Attribute - 0x0000000000004000 +Entry (0x7B4F9718) + Type - 0x5 + PhysicalStart - 0x000000007B5BC000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9748) + Type - 0x6 + PhysicalStart - 0x000000007B5BD000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000004000 +Entry (0x7B4F9778) + Type - 0x5 + PhysicalStart - 0x000000007B5BE000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000003 + Attribute - 0x0000000000020000 +Entry (0x7B4F97A8) + Type - 0x6 + PhysicalStart - 0x000000007B5C1000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000007 + Attribute - 0x0000000000004000 +Entry (0x7B4F97D8) + Type - 0x5 + PhysicalStart - 0x000000007B5C8000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9808) + Type - 0x6 + PhysicalStart - 0x000000007B5C9000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000002 + Attribute - 0x0000000000004000 +Entry (0x7B4F9838) + Type - 0x5 + PhysicalStart - 0x000000007B5CB000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000004 + Attribute - 0x0000000000020000 +Entry (0x7B4F9868) + Type - 0x6 + PhysicalStart - 0x000000007B5CF000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000006 + Attribute - 0x0000000000004000 +Entry (0x7B4F9898) + Type - 0x5 + PhysicalStart - 0x000000007B5D5000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F98C8) + Type - 0x6 + PhysicalStart - 0x000000007B5D6000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000004000 +Entry (0x7B4F98F8) + Type - 0x5 + PhysicalStart - 0x000000007B5D7000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000004 + Attribute - 0x0000000000020000 +Entry (0x7B4F9928) + Type - 0x6 + PhysicalStart - 0x000000007B5DB000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000007 + Attribute - 0x0000000000004000 +Entry (0x7B4F9958) + Type - 0x5 + PhysicalStart - 0x000000007B5E2000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9988) + Type - 0x6 + PhysicalStart - 0x000000007B5E3000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000004000 +Entry (0x7B4F99B8) + Type - 0x5 + PhysicalStart - 0x000000007B5E4000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000002 + Attribute - 0x0000000000020000 +Entry (0x7B4F99E8) + Type - 0x6 + PhysicalStart - 0x000000007B5E6000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000005 + Attribute - 0x0000000000004000 +Entry (0x7B4F9A18) + Type - 0x5 + PhysicalStart - 0x000000007B5EB000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9A48) + Type - 0x6 + PhysicalStart - 0x000000007B5EC000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000013 + Attribute - 0x0000000000004000 +Entry (0x7B4F9A78) + Type - 0x5 + PhysicalStart - 0x000000007B5FF000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9AA8) + Type - 0x6 + PhysicalStart - 0x000000007B600000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000045 + Attribute - 0x0000000000004000 +Entry (0x7B4F9AD8) + Type - 0x5 + PhysicalStart - 0x000000007B645000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9B08) + Type - 0x6 + PhysicalStart - 0x000000007B646000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000018 + Attribute - 0x0000000000004000 +Entry (0x7B4F9B38) + Type - 0x5 + PhysicalStart - 0x000000007B65E000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x000000000000000E + Attribute - 0x0000000000020000 +Entry (0x7B4F9B68) + Type - 0x6 + PhysicalStart - 0x000000007B66C000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000004000 +Entry (0x7B4F9B98) + Type - 0x5 + PhysicalStart - 0x000000007B66D000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x000000000000000E + Attribute - 0x0000000000020000 +Entry (0x7B4F9BC8) + Type - 0x6 + PhysicalStart - 0x000000007B67B000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x000000000000000A + Attribute - 0x0000000000004000 +Entry (0x7B4F9BF8) + Type - 0x5 + PhysicalStart - 0x000000007B685000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9C28) + Type - 0x6 + PhysicalStart - 0x000000007B686000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000004000 +Entry (0x7B4F9C58) + Type - 0x5 + PhysicalStart - 0x000000007B687000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000009 + Attribute - 0x0000000000020000 +Entry (0x7B4F9C88) + Type - 0x6 + PhysicalStart - 0x000000007B690000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000007 + Attribute - 0x0000000000004000 +Entry (0x7B4F9CB8) + Type - 0x5 + PhysicalStart - 0x000000007B697000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9CE8) + Type - 0x6 + PhysicalStart - 0x000000007B698000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000002 + Attribute - 0x0000000000004000 +Entry (0x7B4F9D18) + Type - 0x5 + PhysicalStart - 0x000000007B69A000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x000000000000000B + Attribute - 0x0000000000020000 +Entry (0x7B4F9D48) + Type - 0x6 + PhysicalStart - 0x000000007B6A5000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000006 + Attribute - 0x0000000000004000 +Entry (0x7B4F9D78) + Type - 0x5 + PhysicalStart - 0x000000007B6AB000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9DA8) + Type - 0x6 + PhysicalStart - 0x000000007B6AC000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000098 + Attribute - 0x0000000000004000 +Entry (0x7B4F9DD8) + Type - 0x5 + PhysicalStart - 0x000000007B744000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000056 + Attribute - 0x0000000000020000 +Entry (0x7B4F9E08) + Type - 0x6 + PhysicalStart - 0x000000007B79A000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x000000000000003E + Attribute - 0x0000000000004000 +Entry (0x7B4F9E38) + Type - 0x5 + PhysicalStart - 0x000000007B7D8000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9E68) + Type - 0x6 + PhysicalStart - 0x000000007B7D9000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000002 + Attribute - 0x0000000000004000 +Entry (0x7B4F9E98) + Type - 0x5 + PhysicalStart - 0x000000007B7DB000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000002 + Attribute - 0x0000000000020000 +Entry (0x7B4F9EC8) + Type - 0x6 + PhysicalStart - 0x000000007B7DD000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000006 + Attribute - 0x0000000000004000 +Entry (0x7B4F9EF8) + Type - 0x5 + PhysicalStart - 0x000000007B7E3000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000001 + Attribute - 0x0000000000020000 +Entry (0x7B4F9F28) + Type - 0x6 + PhysicalStart - 0x000000007B7E4000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000008 + Attribute - 0x0000000000004000 +Entry (0x7B4F9F58) + Type - 0x5 + PhysicalStart - 0x000000007B7EC000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x000000000000000B + Attribute - 0x0000000000020000 +Entry (0x7B4F9F88) + Type - 0x6 + PhysicalStart - 0x000000007B7F7000 + VirtualStart - 0x0000000000000000 + NumberOfPages - 0x0000000000000009 + Attribute - 0x0000000000004000 +PatchSmmSaveStateMap: +PatchGdtIdtMap - GDT: +PatchGdtIdtMap - IDT: +SetUefiMemMapAttributes +UefiMemory protection: 0x0 - 0x9F000 Success +UefiMemory protection: 0x100000 - 0x20000000 Success +UefiMemory protection: 0x20100000 - 0x79CFE000 Success +UefiMemory protection: 0x79FBE000 - 0x7B000000 Success +UefiMemoryAttribute protection: 0x79E7C000 - 0x79E80000 Success +UefiMemoryAttribute protection: 0x79E86000 - 0x79E88000 Success +UefiMemoryAttribute protection: 0x79E8D000 - 0x79E92000 Success +UefiMemoryAttribute protection: 0x79E99000 - 0x79E9E000 Success +UefiMemoryAttribute protection: 0x79EA5000 - 0x79EAA000 Success +UefiMemoryAttribute protection: 0x79EB1000 - 0x79EB4000 Success +UefiMemoryAttribute protection: 0x79EBC000 - 0x79EC6000 Success +UefiMemoryAttribute protection: 0x79ECD000 - 0x79ED3000 Success +UefiMemoryAttribute protection: 0x79EDA000 - 0x79EDF000 Success +UefiMemoryAttribute protection: 0x79EE5000 - 0x79EE7000 Success +UefiMemoryAttribute protection: 0x79EEE000 - 0x79EF0000 Success +UefiMemoryAttribute protection: 0x79EF5000 - 0x79EF8000 Success +SetPageTableAttributes +Start... +SMM IPL locked SMRAM window +D0 Stepping Detected +SmbiosAdd: Smbios type 1 with size 0x71 is added to 32-bit table +SmbiosAdd: Smbios type 1 with size 0x71 is added to 64-bit table +VBT data found +ExitPmAuth ()- End +[Bds]RegisterKeyNotify: 000C/0000 80000000/00 Success +[Bds]RegisterKeyNotify: 0011/0000 80000000/00 Success +[Bds]RegisterKeyNotify: 0000/000D 80000000/00 Success +InstallProtocolInterface: F749DEBC-42E6-4F59-821E-1E94EE9FBBB1 79527098 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78C93418 +InstallProtocolInterface: 215FDD18-BD50-4FEB-890B-58CA0B4739E9 78939838 +ClockRate = 1843200 +Divisor = 1 +BaudRate/Actual (115200/115200) = 100% +ClockRate = 1843200 +Divisor = 1 +BaudRate/Actual (115200/115200) = 100% +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 7892FA98 +InstallProtocolInterface: BB25CF6F-F1D4-11D2-9A0C-0090273FC1FD 7892F2A8 +PciSioSerial: Create SIO child serial device - Success +ClockRate = 1843200 +Divisor = 1 +BaudRate/Actual (115200/115200) = 100% +Terminal - Mode 0, Column = 80, Row = 25 +Terminal - Mode 1, Column = 80, Row = 50 +Terminal - Mode 2, Column = 100, Row = 31 +ClockRate = 1843200 +Divisor = 1 +BaudRate/Actual (115200/115200) = 100% +InstallProtocolInterface: 387477C1-69C7-11D2-8E39-00A0C969723B 7892ED40 +InstallProtocolInterface: DD9E7534-7762-4698-8C14-F58517A625AA 7892EE28 +InstallProtocolInterface: 387477C2-69C7-11D2-8E39-00A0C969723B 7892ED58 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 7892F518 +InstallProtocolInterface: D3B36F2B-D551-11D4-9A46-0090273FC14D 0 +InstallProtocolInterface: D3B36F2C-D551-11D4-9A46-0090273FC14D 0 +XhcCreateUsb3Hc: Capability length 0x80 +XhcCreateUsb3Hc: HcSParams1 0x7000820 +XhcCreateUsb3Hc: HcSParams2 0x84000054 +XhcCreateUsb3Hc: HcCParams 0x200077C1 +XhcCreateUsb3Hc: DBOff 0x3000 +XhcCreateUsb3Hc: RTSOff 0x2000 +XhcCreateUsb3Hc: UsbLegSupOffset 0x460 +XhcCreateUsb3Hc: DebugCapSupOffset 0x480 +XhcSetBiosOwnership: called to set BIOS ownership +XhcResetHC! +XhcInitSched:DCBAA=0x785F7000 +XhcInitSched: Created CMD ring [785F7140~785F8140) EVENT ring [785F8140~785FA140) +InstallProtocolInterface: 3E745226-9818-45B6-A2AC-D7CD0E8BA2BC 78607038 +XhcDriverBindingStart: XHCI started for controller @ 78A03C98 +InstallProtocolInterface: 240612B7-A063-11D4-9A3A-0090273FC14D 785EF020 +XhcGetCapability: 7 ports, 64 bit 1 +UsbRootHubInit: root hub 7892B598 - max speed 3, 7 ports +UsbBusStart: usb bus started on 78A03C98, root hub 7892B598 +PlatformBootManagerAfterConsole +PlatformBootManagerAfterConsole: BootMode = 0 +SdMmcPciHcDriverBindingStart: Start + == Slot [0] Capability is 0x785EDE80 == + Timeout Clk Freq 50MHz + Base Clk Freq 100MHz + Max Blk Len 2048bytes + 8-bit Support FALSE + ADMA2 Support TRUE + HighSpeed Support TRUE + SDMA Support TRUE + Suspend/Resume FALSE + Voltage 3.3 TRUE + Voltage 3.0 TRUE + Voltage 1.8 TRUE + V4 64-bit Sys Bus FALSE + V3 64-bit Sys Bus FALSE + Async Interrupt TRUE + SlotType Embedded Slot + SDR50 Support FALSE + SDR104 Support FALSE + DDR50 Support TRUE + Driver Type A FALSE + Driver Type C FALSE + Driver Type D FALSE + Driver Type 4 FALSE + Retuning TimerCnt Disabled + SDR50 Tuning FALSE + Retuning Mode Mode 1 + Clock Multiplier M = 1 + HS 400 FALSE +Slot[0] Base Clock Frequency: 100MHz +BaseClkFreq 100MHz Divisor 125 ClockFreq 400Khz +Error reported by SDHCI +Interrupt status = 8040 +Error interrupt status = 1 +TRB failed with Device Error +Printing SD_MMC_HC_TRB +Slot: 0 +BlockSize: 512 +Data: 0 +DataLen: 0 +Read: 0 +DataPhy: 0 +DataMap: 0 +Mode: 0 +AdmaLengthMode: 0 +Event: 0 +Started: 0 +CommandComplete: 0 +Timeout: 1000000 +Retries: 5 +PioModeTransferCompleted: 0 +PioBlockIndex: 0 +Adma32Desc: 0 +Adma64V3Desc: 0 +Adma64V4Desc: 0 +AdmaMap: 0 +AdmaPages: 0 +Printing EFI_SD_MMC_PASS_THRU_COMMAND_PACKET +Command index: 1, argument: 0 +Command type: 1, response type: 3 +Response 0: 0, 1: 0, 2: 0, 3: 0 +Timeout: 1000000 +InDataBuffer: 0 +OutDataBuffer: 0 +InTransferLength: 0 +OutTransferLength: 0 +TransactionStatus: Success +Error reported by SDHCI +Interrupt status = 8040 +Error interrupt status = 1 +TRB failed with Device Error +Printing SD_MMC_HC_TRB +Slot: 0 +BlockSize: 512 +Data: 0 +DataLen: 0 +Read: 0 +DataPhy: 0 +DataMap: 0 +Mode: 0 +AdmaLengthMode: 0 +Event: 0 +Started: 0 +CommandComplete: 0 +Timeout: 1000000 +Retries: 5 +PioModeTransferCompleted: 0 +PioBlockIndex: 0 +Adma32Desc: 0 +Adma64V3Desc: 0 +Adma64V4Desc: 0 +AdmaMap: 0 +AdmaPages: 0 +Printing EFI_SD_MMC_PASS_THRU_COMMAND_PACKET +Command index: 8, argument: 1FF +Command type: 1, response type: 8 +Response 0: 0, 1: 0, 2: 0, 3: 0 +Timeout: 1000000 +InDataBuffer: 0 +OutDataBuffer: 0 +InTransferLength: 0 +OutTransferLength: 0 +TransactionStatus: Success +SdCardIdentification: Executing Cmd8 fails with Device Error +InstallProtocolInterface: 716EF0D9-FF83-4F69-81E9-518BD39A8E70 785EDD30 +SdMmcPciHcDriverBindingStart: Success End on 78A01A98 +InstallProtocolInterface: 2145F72F-E6F1-4440-A828-59DC9AAB5F89 785E8018 +InstallProtocolInterface: 430AC2F7-EEC6-4093-94F7-9F825A7C1C40 785EDB18 +SdMmcPciHcDriverBindingStart: Start + == Slot [0] Capability is 0x785EEC00 == + Timeout Clk Freq 50MHz + Base Clk Freq 100MHz + Max Blk Len 512bytes + 8-bit Support FALSE + ADMA2 Support TRUE + HighSpeed Support TRUE + SDMA Support TRUE + Suspend/Resume FALSE + Voltage 3.3 TRUE + Voltage 3.0 TRUE + Voltage 1.8 TRUE + V4 64-bit Sys Bus FALSE + V3 64-bit Sys Bus FALSE + Async Interrupt FALSE + SlotType Removable Slot + SDR50 Support FALSE + SDR104 Support FALSE + DDR50 Support FALSE + Driver Type A FALSE + Driver Type C FALSE + Driver Type D FALSE + Driver Type 4 FALSE + Retuning TimerCnt Disabled + SDR50 Tuning FALSE + Retuning Mode Mode 1 + Clock Multiplier M = 1 + HS 400 FALSE +Slot[0] Base Clock Frequency: 100MHz +SdMmcHcCardDetect: No device attached in Slot[0]!!! +InstallProtocolInterface: 716EF0D9-FF83-4F69-81E9-518BD39A8E70 785EEAB0 +SdMmcPciHcDriverBindingStart: Success End on 78A09E18 +InstallProtocolInterface: 2145F72F-E6F1-4440-A828-59DC9AAB5F89 785E7018 +InstallProtocolInterface: 430AC2F7-EEC6-4093-94F7-9F825A7C1C40 785ECB18 +SataControllerStart() Start +InstallProtocolInterface: BB929DA9-68F7-4035-B22C-A3BB3F23DA55 785EC098 +InstallProtocolInterface: A1E37052-80D9-4E65-A317-3E9A55C43EC9 785EC0A0 +SataControllerStart() End +==AtaAtapiPassThru Start== Controller = 78A03E18 +SdMmcPciHcDriverBindingStart: Start + == Slot [0] Capability is 0x785EBD00 == + Timeout Clk Freq 1KHz + Base Clk Freq 200MHz + Max Blk Len 512bytes + 8-bit Support TRUE + ADMA2 Support TRUE + HighSpeed Support TRUE + SDMA Support TRUE + Suspend/Resume FALSE + Voltage 3.3 FALSE + Voltage 3.0 FALSE + Voltage 1.8 TRUE + V4 64-bit Sys Bus FALSE + V3 64-bit Sys Bus FALSE + Async Interrupt FALSE + SlotType Embedded Slot + SDR50 Support TRUE + SDR104 Support TRUE + DDR50 Support TRUE + Driver Type A FALSE + Driver Type C FALSE + Driver Type D FALSE + Driver Type 4 FALSE + Retuning TimerCnt 14seconds + SDR50 Tuning FALSE + Retuning Mode Mode 1 + Clock Multiplier M = 1 + HS 400 FALSE +Slot[0] Base Clock Frequency: 200MHz +BaseClkFreq 200MHz Divisor 250 ClockFreq 400Khz +Error reported by SDHCI +Interrupt status = 8040 +Error interrupt status = 1 +TRB failed with Device Error +Printing SD_MMC_HC_TRB +Slot: 0 +BlockSize: 512 +Data: 0 +DataLen: 0 +Read: 0 +DataPhy: 0 +DataMap: 0 +Mode: 0 +AdmaLengthMode: 0 +Event: 0 +Started: 0 +CommandComplete: 0 +Timeout: 1000000 +Retries: 5 +PioModeTransferCompleted: 0 +PioBlockIndex: 0 +Adma32Desc: 0 +Adma64V3Desc: 0 +Adma64V4Desc: 0 +AdmaMap: 0 +AdmaPages: 0 +Printing EFI_SD_MMC_PASS_THRU_COMMAND_PACKET +Command index: 1, argument: 0 +Command type: 1, response type: 3 +Response 0: 0, 1: 0, 2: 0, 3: 0 +Timeout: 1000000 +InDataBuffer: 0 +OutDataBuffer: 0 +InTransferLength: 0 +OutTransferLength: 0 +TransactionStatus: Success +Error reported by SDHCI +Interrupt status = 8040 +Error interrupt status = 1 +TRB failed with Device Error +Printing SD_MMC_HC_TRB +Slot: 0 +BlockSize: 512 +Data: 0 +DataLen: 0 +Read: 0 +DataPhy: 0 +DataMap: 0 +Mode: 0 +AdmaLengthMode: 0 +Event: 0 +Started: 0 +CommandComplete: 0 +Timeout: 1000000 +Retries: 5 +PioModeTransferCompleted: 0 +PioBlockIndex: 0 +Adma32Desc: 0 +Adma64V3Desc: 0 +Adma64V4Desc: 0 +AdmaMap: 0 +AdmaPages: 0 +Printing EFI_SD_MMC_PASS_THRU_COMMAND_PACKET +Command index: 8, argument: 1FF +Command type: 1, response type: 8 +Response 0: 0, 1: 0, 2: 0, 3: 0 +Timeout: 1000000 +InDataBuffer: 0 +OutDataBuffer: 0 +InTransferLength: 0 +OutTransferLength: 0 +TransactionStatus: Success +SdCardIdentification: Executing Cmd8 fails with Device Error +InstallProtocolInterface: 716EF0D9-FF83-4F69-81E9-518BD39A8E70 785EBBB0 +SdMmcPciHcDriverBindingStart: Success End on 78A02F98 +InstallProtocolInterface: 2145F72F-E6F1-4440-A828-59DC9AAB5F89 785E6018 +InstallProtocolInterface: 430AC2F7-EEC6-4093-94F7-9F825A7C1C40 785EB198 +InstallProtocolInterface: 51DD8B21-AD8D-48E9-BC3F-24F46722C748 785E9C80 +InstallProtocolInterface: E3161450-AD0F-11D9-9669-0800200C9A66 785E6048 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 785EA118 +InstallProtocolInterface: E3161450-AD0F-11D9-9669-0800200C9A66 785E6048 +InstallProtocolInterface: 1ACED566-76ED-4218-BC81-767F1F977A89 785E6020 +InstallProtocolInterface: 0E1AD94A-DCF4-11DB-9705-00E08161165F 78828808 +InstallProtocolInterface: 34D59603-1428-4429-A414-E6B3B5FD7DC1 785E9C40 +InstallProtocolInterface: E5DD1403-D622-C24E-8488-C71B17F5E802 785E9CB0 +InstallProtocolInterface: 330D4706-F2A0-4E4F-A369-B66FA8D54385 785E9C28 +Support(): UNDI3.1 found on handle 785EA098 +Support(): supported on 785EA098 +Start(): UNDI3.1 found +InstallProtocolInterface: A19832B9-AC25-11D3-9A2D-0090273FC14D 785A0020 +InstallProtocolInterface: 9E23D768-D2F3-4366-9FC3-3A7ABA864374 7859EC30 +InstallProtocolInterface: F36FF770-A7E1-42CF-9ED2-56F0F271F44C 7849A6C0 +InstallProtocolInterface: 7AB33A91-ACE5-4326-B572-E7EE33D39F16 78499040 + +Snp->undi.initialize() C001h:6h +InstallProtocolInterface: F44C00EE-1F2C-4A00-AA09-1C9F3E0800A3 7849A7A0 +InstallProtocolInterface: 7AB33A91-ACE5-4326-B572-E7EE33D39F16 78496BC0 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2C90 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2C92 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2CCC NumBytes: 0x2E, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2C92 NumBytes: 0x1, Buffer: 0x7B6DF01A +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78495D18 +InstallProtocolInterface: 330D4706-F2A0-4E4F-A369-B66FA8D54385 78496838 +InstallProtocolInterface: C51711E7-B4BF-404A-BFB8-0A048EF1FFE4 78496020 +InstallProtocolInterface: 5B446ED1-E30B-4FAA-871A-3654ECA36080 78496580 +InstallProtocolInterface: 41D94CD2-35B6-455A-8258-D4E51334AADD 78492220 +InstallProtocolInterface: 83F01464-99BD-45E5-B383-AF6305D8E9E6 78492820 +InstallProtocolInterface: 41D94CD2-35B6-455A-8258-D4E51334AADD 7848F5A0 +InstallProtocolInterface: 3AD9DF29-4501-478D-B1F8-7F7FE70E50F3 7848EEB8 +InstallProtocolInterface: 9D9A39D8-BD42-4A73-A4D5-8EE94BE11380 7848F120 +InstallProtocolInterface: 41D94CD2-35B6-455A-8258-D4E51334AADD 78488BA0 +InstallProtocolInterface: 3AD9DF29-4501-478D-B1F8-7F7FE70E50F3 784896B8 +InstallProtocolInterface: 2FE800BE-8F01-4AA6-946B-D71388E1833F 784890A0 +InstallProtocolInterface: 7AB33A91-ACE5-4326-B572-E7EE33D39F16 78485BC0 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2CFC NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2CFE NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2D38 NumBytes: 0x42, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2CFE NumBytes: 0x1, Buffer: 0x7B6DF01A +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78488718 +InstallProtocolInterface: 330D4706-F2A0-4E4F-A369-B66FA8D54385 78486FE8 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2CFE NumBytes: 0x1, Buffer: 0x7B657720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2D7C NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2D7E NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2DB8 NumBytes: 0x56, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2D7E NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2CFE NumBytes: 0x1, Buffer: 0x7B657720 +InstallProtocolInterface: EC835DD3-FE0F-617B-A621-B350C3E13388 78486020 +InstallProtocolInterface: 937FE521-95AE-4D1A-8929-48BCD90AD31A 78486F70 +InstallProtocolInterface: 2C8759D5-5C2D-66EF-925F-B66C101957E2 78480BA0 +InstallProtocolInterface: 66ED4721-3C98-4D3E-81E3-D03DD39A7254 784812A0 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2E10 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2E12 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2E4C NumBytes: 0x26, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2E12 NumBytes: 0x1, Buffer: 0x7B6DF01A +InstallProtocolInterface: 2C8759D5-5C2D-66EF-925F-B66C101957E2 7847DD20 +InstallProtocolInterface: 4F948815-B4B9-43CB-8A33-90E060B34955 7847D038 +InstallProtocolInterface: 9FB9A8A1-2F4A-43A6-889C-D0F7B6C47AD5 7847E130 +InstallProtocolInterface: 2C8759D5-5C2D-66EF-925F-B66C101957E2 7847A420 +InstallProtocolInterface: 4F948815-B4B9-43CB-8A33-90E060B34955 7847B238 +InstallProtocolInterface: D9760FF3-3CCA-4267-80F9-7527FAFA4223 7847B1A0 +InstallProtocolInterface: 41D94CD2-35B6-455A-8258-D4E51334AADD 78479BA0 +InstallProtocolInterface: 00720665-67EB-4A99-BAF7-D3C33A1C7CC9 7847AA40 +InstallProtocolInterface: 2C8759D5-5C2D-66EF-925F-B66C101957E2 78476BA0 +InstallProtocolInterface: EC20EB79-6C1A-4664-9A0D-D2E4CC16D664 78477240 +InstallProtocolInterface: B95E9FDA-26DE-48D2-8807-1F9107AC5E3A 78469030 +InstallProtocolInterface: 8A219718-4EF5-4761-91C8-C0F04BDA9E56 78474120 +InstallProtocolInterface: 41D94CD2-35B6-455A-8258-D4E51334AADD 78468420 +InstallProtocolInterface: 3AD9DF29-4501-478D-B1F8-7F7FE70E50F3 78468EB8 +InstallProtocolInterface: 78247C57-63DB-4708-99C2-A8B4A9A61F6B 784742B0 +InstallProtocolInterface: 41D94CD2-35B6-455A-8258-D4E51334AADD 78467D20 +InstallProtocolInterface: 3AD9DF29-4501-478D-B1F8-7F7FE70E50F3 78467038 +InstallProtocolInterface: 41D94CD2-35B6-455A-8258-D4E51334AADD 784673A0 +InstallProtocolInterface: 3AD9DF29-4501-478D-B1F8-7F7FE70E50F3 78467238 +InstallProtocolInterface: F4B427BB-BA21-4F16-BC4E-43E416AB619C 78466CB0 +InstallProtocolInterface: 41D94CD2-35B6-455A-8258-D4E51334AADD 784668A0 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78466518 +InstallProtocolInterface: 56EC3091-954C-11D2-8E3F-00A0C969723B 784666A8 +InstallProtocolInterface: 03C4E603-AC28-11D3-9A2D-0090273FC14D 78469120 +InstallProtocolInterface: A19832B9-AC25-11D3-9A2D-0090273FC14D 785A0020 +InstallProtocolInterface: 87C8BAD7-0595-4053-8297-DEDE395F5D5B 78465C40 +InstallProtocolInterface: BF0A78BA-EC29-49CF-A1C9-7AE54EAB6A51 784651B8 +InstallProtocolInterface: 2C8759D5-5C2D-66EF-925F-B66C101957E2 78464BA0 +InstallProtocolInterface: 4F948815-B4B9-43CB-8A33-90E060B34955 78465438 +InstallProtocolInterface: 2C8759D5-5C2D-66EF-925F-B66C101957E2 784643A0 +InstallProtocolInterface: 4F948815-B4B9-43CB-8A33-90E060B34955 78464238 +InstallProtocolInterface: 2C8759D5-5C2D-66EF-925F-B66C101957E2 78463120 +InstallProtocolInterface: 09576E91-6D3F-11D2-8E39-00A0C969723B 78463D18 +InstallProtocolInterface: 56EC3091-954C-11D2-8E3F-00A0C969723B 78465BA8 +InstallProtocolInterface: 03C4E603-AC28-11D3-9A2D-0090273FC14D 78469120 +InstallProtocolInterface: A19832B9-AC25-11D3-9A2D-0090273FC14D 785A0020 +InstallProtocolInterface: 2145F72F-E6F1-4440-A828-59DC9AAB5F89 7845A018 +InstallProtocolInterface: 430AC2F7-EEC6-4093-94F7-9F825A7C1C40 7845FE18 +InstallProtocolInterface: 2145F72F-E6F1-4440-A828-59DC9AAB5F89 7845A018 +InstallProtocolInterface: 430AC2F7-EEC6-4093-94F7-9F825A7C1C40 7845FE18 +==AtaAtapiPassThru Start== Controller = 78A03E18 +InstallProtocolInterface: 2145F72F-E6F1-4440-A828-59DC9AAB5F89 7845A018 +InstallProtocolInterface: 430AC2F7-EEC6-4093-94F7-9F825A7C1C40 7892B518 +Support(): Already Started. on handle 785EA098 +Support(): Already Started. on handle 785EA098 +Support(): Already Started. on handle 785EA098 +Support(): Already Started. on handle 785EA098 +Support(): Already Started. on handle 785EA098 +Support(): Already Started. on handle 785EA098 +Support(): Already Started. on handle 785EA098 +Support(): Already Started. on handle 785EA098 +Support(): Already Started. on handle 785EA098 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2A12 NumBytes: 0x1, Buffer: 0x7B657720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2E74 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2E76 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2EB0 NumBytes: 0x1C, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2E76 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2A12 NumBytes: 0x1, Buffer: 0x7B657720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2ECC NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2ECE NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2F08 NumBytes: 0xC0, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2ECE NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2E76 NumBytes: 0x1, Buffer: 0x7B657720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2FC8 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2FCA NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x3004 NumBytes: 0x1E, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x2FCA NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2E76 NumBytes: 0x1, Buffer: 0x7B657720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x3024 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x3026 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x3060 NumBytes: 0xE1, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x3026 NumBytes: 0x1, Buffer: 0x7B6DF01A +PcdBootState = 1 +FvbProtocolWrite: Lba: 0x0 Offset: 0x116 NumBytes: 0x1, Buffer: 0x7B651720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x3144 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x3146 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x3180 NumBytes: 0x15, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x3146 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x116 NumBytes: 0x1, Buffer: 0x7B651720 +MnpAddFreeTxBuf: Add TxBufWrap 785EE018, TxBuf 785EE041 +MnpAddFreeTxBuf: Add TxBufWrap 7845D018, TxBuf 7845D041 +MnpAddFreeTxBuf: Add TxBufWrap 7845D698, TxBuf 7845D6C1 +MnpAddFreeTxBuf: Add TxBufWrap 7845C018, TxBuf 7845C041 +MnpAddFreeTxBuf: Add TxBufWrap 7845C698, TxBuf 7845C6C1 +MnpAddFreeTxBuf: Add TxBufWrap 7845B018, TxBuf 7845B041 +MnpAddFreeTxBuf: Add TxBufWrap 7845B698, TxBuf 7845B6C1 +MnpAddFreeTxBuf: Add TxBufWrap 7845A018, TxBuf 7845A041 +MnpAddFreeTxBuf: Add TxBufWrap 7845A698, TxBuf 7845A6C1 +MnpAddFreeTxBuf: Add TxBufWrap 78459018, TxBuf 78459041 +MnpAddFreeTxBuf: Add TxBufWrap 78459698, TxBuf 784596C1 +MnpAddFreeTxBuf: Add TxBufWrap 78458018, TxBuf 78458041 +MnpAddFreeTxBuf: Add TxBufWrap 78458698, TxBuf 784586C1 +MnpAddFreeTxBuf: Add TxBufWrap 78457018, TxBuf 78457041 +MnpAddFreeTxBuf: Add TxBufWrap 78457698, TxBuf 784576C1 +MnpAddFreeTxBuf: Add TxBufWrap 78456018, TxBuf 78456041 +MnpAddFreeTxBuf: Add TxBufWrap 78456698, TxBuf 784566C1 +MnpAddFreeTxBuf: Add TxBufWrap 78455018, TxBuf 78455041 +MnpAddFreeTxBuf: Add TxBufWrap 78455698, TxBuf 784556C1 +MnpAddFreeTxBuf: Add TxBufWrap 78454018, TxBuf 78454041 +MnpAddFreeTxBuf: Add TxBufWrap 78454698, TxBuf 784546C1 +MnpAddFreeTxBuf: Add TxBufWrap 78453018, TxBuf 78453041 +MnpAddFreeTxBuf: Add TxBufWrap 78453698, TxBuf 784536C1 +MnpAddFreeTxBuf: Add TxBufWrap 78452018, TxBuf 78452041 +MnpAddFreeTxBuf: Add TxBufWrap 78452698, TxBuf 784526C1 +MnpAddFreeTxBuf: Add TxBufWrap 78451018, TxBuf 78451041 +MnpAddFreeTxBuf: Add TxBufWrap 78451698, TxBuf 784516C1 +MnpAddFreeTxBuf: Add TxBufWrap 78450018, TxBuf 78450041 +MnpAddFreeTxBuf: Add TxBufWrap 78450698, TxBuf 784506C1 +MnpAddFreeTxBuf: Add TxBufWrap 7844F018, TxBuf 7844F041 +MnpAddFreeTxBuf: Add TxBufWrap 7844F698, TxBuf 7844F6C1 +MnpAddFreeTxBuf: Add TxBufWrap 7844E018, TxBuf 7844E041 +MnpSyncSendPacket: No network cable detected. +PcdBootState = 0 +Press F7 for BootMenu! +FvbProtocolWrite: Lba: 0x0 Offset: 0x2FCA NumBytes: 0x1, Buffer: 0x7B65D720 +FvbProtocolWrite: Lba: 0x0 Offset: 0x3198 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x319A NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x31D4 NumBytes: 0x1E, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x319A NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x2FCA NumBytes: 0x1, Buffer: 0x7B65D720 +********************************** +** WARNING: Test Key is used. ** +********************************** +** WARNING: Test Key is used. ** +[Bds]OsIndication: 0000000000000000 +[Bds]=============Begin Load Options Dumping ...============= + Driver Options: + SysPrep Options: + Boot Options: + Boot0003: UEFI PXEv4 (MAC:0008A20F741E) 0x0001 + Boot0004: UEFI PXEv6 (MAC:0008A20F741E) 0x0001 + Boot0001: Internal UEFI Shell 2.0 0x0001 + Boot0000: Enter Setup 0x0109 + Boot0002: Boot Device List 0x0109 + PlatformRecovery Options: + PlatformRecovery0000: Default PlatformRecoveMnpSyncSendPacket: No network cable detected. +ry 0x0001 +[Bds]=============End Load Options Dumping============= +[Bds]BdsWait ...Zzzzzzzzzzzz... +[Bds]BdsWait(5)..Zzzz... +[Bds]BdsWait(4)..Zzzz... +[Bds]BdsWait(3)..Zzzz... +[Bds]BdsWait(2)..Zzzz... +[Bds]BdsWait(1)..Zzzz... +[Bds]Exit the waiting! +=============ISPBase=90800000============== + +[Bds]Stop Hotkey Service! +[Bds]UnregisterKeyNotify: 000C/0000 Success +[Bds]UnregisterKeyNotify: 0011/0000 Success +[Bds]UnregisterKeyNotify: 0000/000D Success +OnReadyToBootCallBack +PchInitAfterPciEnumeration - Callback. +ConfigureMiscAtBoot() Start +ConfigureMiscAtBoot() End +ConfigureLpeAtBoot() Start +ConfigureLpeAtBoot() End +ConfigureOtgAtBoot() Start +ConfigureOtgAtBoot() End +ConfigureLpssAtBoot() Start +RootBridgeHandle 79435998 1 + 8A 2B 1 0 0 0 1000 0 0 2000 + 8A 2B 0 0 0 20 80000000 0 0 10800000 +Update Device 0 11 0 +Devices 8A 2B 0 0 0 20 90733000 FFF 0 1000 +New Resource is 0 90C00000 +Devices 8A 2B 0 0 0 20 90732000 FFF 0 1000 +New Resource is 1 90C01000 +Update Device 0 18 0 +Devices 8A 2B 0 0 0 20 90718000 3FFF 0 4000 +New Resource is 0 90C04000 +Devices 8A 2B 0 0 0 20 9072C000 FFF 0 1000 +New Resource is 1 90C02000 +Update Device 0 18 6 +Devices 8A 2B 0 0 0 20 9072B000 FFF 0 1000 +New Resource is 0 90C03000 +Devices 8A 2B 0 0 0 20 9072A000 FFF 0 1000 +New Resource is 1 90C08000 +Update Device 0 18 7 +Devices 8A 2B 0 0 0 20 90729000 FFF 0 1000 +New Resource is 0 90C09000 +Devices 8A 2B 0 0 0 20 90728000 FFF 0 1000 +New Resource is 1 90C0A000 +Update Device 0 1E 0 +Devices 8A 2B 0 0 0 20 90714000 3FFF 0 4000 +New Resource is 0 90C0C000 +Devices 8A 2B 0 0 0 20 90727000 FFF 0 1000 +New Resource is 1 90C0B000 +Update Device 0 1E 1 +Devices 8A 2B 0 0 0 20 90726000 FFF 0 1000 +New Resource is 0 90C10000 +Devices 8A 2B 0 0 0 20 90725000 FFF 0 1000 +New Resource is 1 90C11000 +Update Device 0 1E 2 +Devices 8A 2B 0 0 0 20 90724000 FFF 0 1000 +New Resource is 0 90C12000 +Devices 8A 2B 0 0 0 20 90723000 FFF 0 1000 +New Resource is 1 90C13000 +Update Device 0 1E 3 +Devices 8A 2B 0 0 0 20 90722000 FFF 0 1000 +New Resource is 0 90C14000 +Devices 8A 2B 0 0 0 20 90721000 FFF 0 1000 +New Resource is 1 90C15000 +Update Device 0 1E 4 +Devices 8A 2B 0 0 0 20 90720000 FFF 0 1000 +New Resource is 0 90C16000 +Devices 8A 2B 0 0 0 20 9071F000 FFF 0 1000 +New Resource is 1 90C17000 +Update Device 0 1E 5 +Devices 8A 2B 0 0 0 20 9071E000 FFF 0 1000 +New Resource is 0 90C18000 +Devices 8A 2B 0 0 0 20 9071D000 FFF 0 1000 +New Resource is 1 90C19000 +Initialize CSRT Start +Initialize CSRT End,LpssDMA0Bar0=90C0C000,LpssDMA1Bar0=0 +gLpssDummyProtocolGuid +InstallProtocolInterface: AF4CC162-D41C-455A-AB45-6DBCC1CD32F3 0 +ConfigureLpssAtBoot() End +ConfigureSccAtBoot() Start +ConfigSccBootableDevicesAtBootForS3() Start +Update Device 0 12 0 +Devices 8A 2B 0 0 0 20 90731000 FFF 0 1000 +New Resource is 0 90C1A000 +Devices 8A 2B 0 0 0 20 90730000 FFF 0 1000 +New Resource is 1 90C1B000 +Update Device 0 17 0 +Devices 8A 2B 0 0 0 20 9072E000 FFF 0 1000 +New Resource is 0 90C1C000 +Devices 8A 2B 0 0 0 20 9072D000 FFF 0 1000 +New Resource is 1 90C1D000 +ConfigSccBootableDevicesAtBootForS3() End +ConfigureSccAtBoot() End +ConfigureIrqAtBoot() Start +InitPciDevPME mSystemConfiguration.EhciPllCfgEnable = 0x1 +ConfigureAdditionalPm() EhciPciMmBase = 0xE00E8000 +ConfigureAdditionalPm() R_PCH_EHCI_PWR_CNTL_STS = 0xFFFFFFFF +SmmInstallProtocolInterface: 6E057ECF-FA99-4F39-95BC-59F9921D17E4 0 +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +SmmLockBoxSmmLib UpdateLockBox - Enter +SmmLockBoxSmmLib UpdateLockBox - Exit (Success) +EsrtFmpDxe: Add new image descriptor with GUID 4096267B-DA0A-42EB-B5EB-FEF31D207CB4 HardwareInstance:0x0 +EsrtFmpDxe: Found an ESRT entry for a System Device. +EsrtFmpDxe: Add new image descriptor with GUID 79179BFD-704D-4C90-9E02-0AB8D968C18A HardwareInstance:0x0 +EsrtFmpDxe: Add new image descriptor with GUID 149DA854-7D19-4FAA-A91E-862EA1324BE6 HardwareInstance:0x0 +EsrtFmpDxe: Add new image descriptor with GUID 72E2945A-00DA-448E-9AA7-075AD840F9D4 HardwareInstance:0x0 +EsrtFmpDxe: Add new image descriptor with GUID 96D4FDCD-1502-424D-9D4C-9B12D2DCAE5C HardwareInstance:0x0 +ESRT Table Information: ++--------------------------------------------------------+ +| Firmware Resource Count : 0x00000005 | +| Firmware Resource Count Max : 0x00000008 | +| Firmware Resource Entry Version : 0x0000000000000001 | ++--------------------------------------------------------+ +ESRT Table Entries: ++--------------------------------------+--------------+------------+------------+------------+------------+------------+ +| | | | Lowest | | Last | Last | +| | Firmware | | Supported | Capsule | Attempted | Attempted | +| CLASS GUID | Type | Version | Version | Flags | Version | Status | ++--------------------------------------+--------------+------------+------------+------------+------------+------------+ +| 4096267B-DA0A-42EB-B5EB-FEF31D207CB4 | System FW | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| 79179BFD-704D-4C90-9E02-0AB8D968C18A | Device FW | 0x00000001 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| 149DA854-7D19-4FAA-A91E-862EA1324BE6 | Device FW | 0x00000001 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| 72E2945A-00DA-448E-9AA7-075AD840F9D4 | Device FW | 0x00000001 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| 96D4FDCD-1502-424D-9D4C-9B12D2DCAE5C | Device FW | 0x00000909 | 0x00000909 | 0x00000000 | 0x00000000 | 0x00000000 | ++--------------------------------------+--------------+------------+------------+------------+------------+------------+ +EsrtFmpDxe: Installed ESRT table. +DXE get BIOS ID from FV successfully +BIOS ID: MNW2MAXW.X64.0090.D01.2112181640 +GetBiosVersionDateTime :MNW2MAXW.X64.0090.D01.2112181640 12/18/2021 16:40 +update STR_BIOS_VERSION_VALUE +update STR_BIOS_BUILD_TIME_VALUE +00: - Healthy +Memory Previous Current Next + Type Pages Pages Pages +====== ======== ======== ======== + 09 00000040 00000017 00000040 + 0A 00000040 00000036 00000040 + 00 00000080 0000004D 00000080 + 05 00000100 00000083 00000100 + 06 00000100 000000BF 00000100 +FvbProtocolWrite: Lba: 0x0 Offset: 0x31F4 NumBytes: 0x3C, Buffer: 0x7B6DF018 +FvbProtocolWrite: Lba: 0x0 Offset: 0x31F6 NumBytes: 0x1, Buffer: 0x7B6DF01A +FvbProtocolWrite: Lba: 0x0 Offset: 0x3230 NumBytes: 0x5C, Buffer: 0x7B6DF054 +FvbProtocolWrite: Lba: 0x0 Offset: 0x31F6 NumBytes: 0x1, Buffer: 0x7B6DF01A +[Bds]Booting UEFI PXEv4 (MAC:0008A20F741E) +[Bds] Expand PciRoot(0x0)/Pci(0x1C,0x2)/Pci(0x0,0x0)/MAC(0008A20F741E,0x1)/IPv4(0.0.0.0,0x0,DHCP,0.0.0.0,0.0.0.0,0.0.0.0) -> +OnReadyToBootCallBack +InitPciDevPME mSystemConfiguration.EhciPllCfgEnable = 0x1 +ConfigureAdditionalPm() EhciPciMmBase = 0xE00E8000 +ConfigureAdditionalPm() R_PCH_EHCI_PWR_CNTL_STS = 0xFFFFFFFF +00: - Healthy +Memory Previous Current Next + Type Pages Pages Pages +====== ======== ======== ======== + 09 00000040 00000017 00000040 + 0A 00000040 00000036 00000040 + 00 00000080 0000004D 00000080 + 05 00000100 00000083 00000100 + 06 00000100 000000BF 00000100 +[Bds]Booting UEFI PXEv6 (MAC:0008A20F741E) +[Bds] Expand PciRoot(0x0)/Pci(0x1C,0x2)/Pci(0x0,0x0)/MAC(0008A20F741E,0x1)/IPv6(0000:0000:0000:0000:0000:0000:0000:0000,0x0,Static,0000:0000:0000:0000:0000:0000:0000:0000,0x40,0000:0000:0000:0000:0000:0000:0000:0000) -> +OnReadyToBootCallBack +InitPciDevPME mSystemConfiguration.EhciPllCfgEnable = 0x1 +ConfigureAdditionalPm() EhciPciMmBase = 0xE00E8000 +ConfigureAdditionalPm() R_PCH_EHCI_PWR_CNTL_STS = 0xFFFFFFFF +00: - Healthy +Memory Previous Current Next + Type Pages Pages Pages +====== ======== ======== ======== + 09 00000040 00000017 00000040 + 0A 00000040 00000036 00000040 + 00 00000080 0000004D 00000080 + 05 00000100 00000083 00000100 + 06 00000100 000000BF 00000100 +[Bds]Booting Internal UEFI Shell 2.0 +[Bds] Expand Fv(A881D567-6CB0-4EEE-8435-2E72D33E45B5)/FvFile(7C04A583-9E3E-4F1C-AD65-E05268D0B4D1) -> Fv(A881D567-6CB0-4EEE-8435-2E72D33E45B5)/FvFile(7C04A583-9E3E-4F1C-AD65-E05268D0B4D1) +InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 7892D2C0 +Loading driver at 0x00078256000 EntryPoint=0x000782563F4 Shell.efi +InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 78FC5718 +ProtectUefiImageCommon - 0x7892D2C0 + - 0x0000000078256000 - 0x00000000000EECA0 +[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue. +[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue. +[HiiDatabase]: Memory allocation is required after ReadyToBoot, which may change memory map and cause S4 resume issue. +InstallProtocolInterface: 387477C2-69C7-11D2-8E39-00A0C969723B 7843D120 +InstallProtocolInterface: 752F3136-4E16-4FDC-A22A-E5F46812F4CA 78441D98 +InstallProtocolInterface: 6302D008-7F9B-4F30-87AC-60C9FEF5DA4E 782DE4B0 +UEFI Interactive Shell v2.2 +EDK II +UEFI v2.70 (EDK II, 0x00010000) +Mapping table +map: No mapping found. +Press ESC in 5 seconds to skip startup.nsh or any other key to continue.Press ESC in 4 seconds to skip startup.nsh or any other key to continue.Press ESC in 3 seconds to skip startup.nsh or any other key to continue.MnpSyncSendPacket: No network cable detected. +Press ESC in 2 seconds to skip startup.nsh or any other key to continue.Press ESC in 1 seconds to skip startup.nsh or any other key to continue. +Shell> \ No newline at end of file diff --git a/UEFIBinaries/RELEASE.bin b/UEFIBinaries/RELEASE.bin new file mode 100644 index 00000000000..e1adea05c58 Binary files /dev/null and b/UEFIBinaries/RELEASE.bin differ diff --git a/UEFIBinaries/RELEASE.log b/UEFIBinaries/RELEASE.log new file mode 100644 index 00000000000..a22582d9886 --- /dev/null +++ b/UEFIBinaries/RELEASE.log @@ -0,0 +1,60 @@ + +>>>>SecStartup +>>>>MemoryInit Done + + +---------------- +cdeWelcomePei//a:\edk2-staging2021-12-19\CdePkg\CdeWelcome\main.c(78): INTRODUCTION: "CDETRACE" macro. -> + Parameters are typechecked at build time by compilers from GNU, MICROSOFT and others during 2015 to 2021 +Printing 256 bytes of initilaized memory in a "dump"-format: +0000: 00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F +0010: 10 11 12 13 14 15 16 17 - 18 19 1A 1B 1C 1D 1E 1F +0020: 20 21 22 23 24 25 26 27 - 28 29 2A 2B 2C 2D 2E 2F +0030: 30 31 32 33 34 35 36 37 - 38 39 3A 3B 3C 3D 3E 3F +0040: 40 41 42 43 44 45 46 47 - 48 49 4A 4B 4C 4D 4E 4F +0050: 50 51 52 53 54 55 56 57 - 58 59 5A 5B 5C 5D 5E 5F +0060: 60 61 62 63 64 65 66 67 - 68 69 6A 6B 6C 6D 6E 6F +0070: 70 71 72 73 74 75 76 77 - 78 79 7A 7B 7C 7D 7E 7F +0080: 80 81 82 83 84 85 86 87 - 88 89 8A 8B 8C 8D 8E 8F +0090: 90 91 92 93 94 95 96 97 - 98 99 9A 9B 9C 9D 9E 9F +00A0: A0 A1 A2 A3 A4 A5 A6 A7 - A8 A9 AA AB AC AD AE AF +00B0: B0 B1 B2 B3 B4 B5 B6 B7 - B8 B9 BA BB BC BD BE BF +00C0: C0 C1 C2 C3 C4 C5 C6 C7 - C8 C9 CA CB CC CD CE CF +00D0: D0 D1 D2 D3 D4 D5 D6 D7 - D8 D9 DA DB DC DD DE DF +00E0: E0 E1 E2 E3 E4 E5 E6 E7 - E8 E9 EA EB EC ED EE EF +00F0: F0 F1 F2 F3 F4 F5 F6 F7 - F8 F9 FA FB FC FD FE FF +3s... 2s... 1s... 0s... + + +---------------- +cdeWelcomeDxe//a:\edk2-staging2021-12-19\CdePkg\CdeWelcome\main.c(78): INTRODUCTION: "CDETRACE" macro. -> + Parameters are typechecked at build time by compilers from GNU, MICROSOFT and others during 2015 to 2021 +Printing 256 bytes of initilaized memory in a "dump"-format: +0000: 00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F +0010: 10 11 12 13 14 15 16 17 - 18 19 1A 1B 1C 1D 1E 1F +0020: 20 21 22 23 24 25 26 27 - 28 29 2A 2B 2C 2D 2E 2F +0030: 30 31 32 33 34 35 36 37 - 38 39 3A 3B 3C 3D 3E 3F +0040: 40 41 42 43 44 45 46 47 - 48 49 4A 4B 4C 4D 4E 4F +0050: 50 51 52 53 54 55 56 57 - 58 59 5A 5B 5C 5D 5E 5F +0060: 60 61 62 63 64 65 66 67 - 68 69 6A 6B 6C 6D 6E 6F +0070: 70 71 72 73 74 75 76 77 - 78 79 7A 7B 7C 7D 7E 7F +0080: 80 81 82 83 84 85 86 87 - 88 89 8A 8B 8C 8D 8E 8F +0090: 90 91 92 93 94 95 96 97 - 98 99 9A 9B 9C 9D 9E 9F +00A0: A0 A1 A2 A3 A4 A5 A6 A7 - A8 A9 AA AB AC AD AE AF +00B0: B0 B1 B2 B3 B4 B5 B6 B7 - B8 B9 BA BB BC BD BE BF +00C0: C0 C1 C2 C3 C4 C5 C6 C7 - C8 C9 CA CB CC CD CE CF +00D0: D0 D1 D2 D3 D4 D5 D6 D7 - D8 D9 DA DB DC DD DE DF +00E0: E0 E1 E2 E3 E4 E5 E6 E7 - E8 E9 EA EB EC ED EE EF +00F0: F0 F1 F2 F3 F4 F5 F6 F7 - F8 F9 FA FB FC FD FE FF +3s... 2s... 1s... 0s... +Press F7 for BootMenu! +** WARNING: Test Key is used. ** +UEFI Interactive Shell v2.2 +EDK II +UEFI v2.70 (EDK II, 0x00010000) +Mapping table +map: No mapping found. +Press ESC in 5 seconds to skip startup.nsh or any other key to continue.Press ESC in 4 seconds to skip startup.nsh or any other key to continue.Press ESC in 3 seconds to skip startup.nsh or any other key to continue.Press ESC in 2 seconds to skip startup.nsh or any other key to continue.Press ESC in 1 seconds to skip startup.nsh or any other key to continue. +Shell> welcome to the jungle... +'welcome' is not recognized as an internal or external command, operable program, or script file. +Shell> \ No newline at end of file diff --git a/archview.png b/archview.png new file mode 100644 index 00000000000..486ba2c92a6 Binary files /dev/null and b/archview.png differ diff --git a/bld.BAT b/bld.BAT new file mode 100644 index 00000000000..9d5bf68e62d --- /dev/null +++ b/bld.BAT @@ -0,0 +1,52 @@ +@echo off +REM check command line parameters + +if /I "EMU" == "%1" goto STARTEMULATIONBUILD +if /I "REL" == "%1" goto STARTMINNOWBOARDBUILD +if /I "DEB" == "%1" goto STARTMINNOWBOARDBUILD + +REM +REM help text +REM +echo. +echo unknown parameter "%1" +echo. +echo type "BLD EMU" for EMULATION build +echo type "BLD REL" for MinnowBoard RELEASE build +echo type "BLD DEB" for MinnowBoard DEBUG build +goto EOF +:STARTEMULATIONBUILD + echo EMULATION build + cd %~p0\edk2 + call build -p EmulatorPkg.dsc -t VS2015x86 -a IA32 + echo type "RUNEMU.bat" to run the emulation build + echo type "DBGEMU.bat" to debug the emulation build + goto EOF + +:STARTMINNOWBOARDBUILD +if exist %~p0Build\Vlv2TbltDevicePkgX64\%1_VS2015x86\FV\VLV.old ( + del %~p0Build\Vlv2TbltDevicePkgX64\%1_VS2015x86\FV\VLV.old +) +if exist %~p0Build\Vlv2TbltDevicePkgX64\%1_VS2015x86\FV\VLV.fd ( + ren %~p0Build\Vlv2TbltDevicePkgX64\%1_VS2015x86\FV\VLV.fd vlv.old +) +cd %~p0\edk2 +if /I "REL" == "%1" ( + set BUILDTYPE=RELEASE +) + +if /I "DEB" == "%1" ( + set BUILDTYPE=DEBUG +) + +ECHO %BUILDTYPE% build +if exist %~p0Build\Vlv2TbltDevicePkgX64\%BUILDTYPE%_VS2015x86\FV\VLV.fd ( + del %~p0Build\Vlv2TbltDevicePkgX64\%BUILDTYPE%_VS2015x86\FV\VLV.fd +) +call build -a IA32 -a X64 -n 5 -t VS2015x86 -b %BUILDTYPE% -p PlatformPkgX64.dsc + +if exist %~p0Build\Vlv2TbltDevicePkgX64\%BUILDTYPE%_VS2015x86\FV\VLV.fd ( + echo copy /y /b %~p0Build\Vlv2TbltDevicePkgX64\%BUILDTYPE%_VS2015x86\FV\VLV.fd %~p0UEFIBinaries\%BUILDTYPE%.bin + copy /y /b %~p0Build\Vlv2TbltDevicePkgX64\%BUILDTYPE%_VS2015x86\FV\VLV.fd %~p0UEFIBinaries\%BUILDTYPE%.bin +) +:EOF \ No newline at end of file diff --git a/blogs/2021-11-14/.gitignore b/blogs/2021-11-14/.gitignore new file mode 100644 index 00000000000..1c9b31830de --- /dev/null +++ b/blogs/2021-11-14/.gitignore @@ -0,0 +1,2 @@ +*.efi +*.obj diff --git a/blogs/2021-11-14/README.md b/blogs/2021-11-14/README.md new file mode 100644 index 00000000000..58450998ae0 --- /dev/null +++ b/blogs/2021-11-14/README.md @@ -0,0 +1,322 @@ +### CdePkgBlog 2021-11-14 +# My legacy toolbox +### Table of content +* [Abstract](README.md#Abstract) +* [Introduction](README.md#Introduction) + * [introductory email](https://edk2.groups.io/g/devel/message/83734?p=%2C%2C%2C20%2C0%2C0%2C0%3A%3ACreated%2C%2CCdePkgBlog%2C20%2C2%2C0%2C87053945) +* [Starting Visual Studio](README.md#starting-visual-studio-2022) +* [Using the compiler and linker](README.md#using-the-compiler-and-linker) + * [Compiling the .C file](README.md#compiling-the-c-file) + * [Linking the .OBJ module to an UEFI Application](README.md#linking-the-obj-module-to-an-uefi-application) +* [Validating correctness / testing equivalence](README.md#validating-correctness--testing-equivalence) + * [Linking the .OBJ module to a Windows x64 command line Application](README.md#linking-the-obj-module-to-a-windows-x64-command-line-application) + * [Linking the .OBJ module to a Windows x64 command line Application based on Microsoft LIBCMT.lib](README.md#linking-the-obj-module-to-a-windows-x64-command-line-application-based-on-microsoft-libcmtlib) +* [Simple tools](README.md#simple-tools) + * [rtcdmp - RTC dump tool](README.md#rtcdmp---rtc-dump-tool) + * [rtcwr - RTC write tool](README.md#rtcwr---rtc-write-tool) + * [iodmp - I/O dump tool](README.md#iodmp---io-dump-tool) + * [iowr - I/O write tool](README.md#iowr---io-write-tool) +* [My legacy toolbox](README.md#my-legacy-toolbox) +* [Coming up soon](README.md#coming-up-soon) + +## Abstract +Demonstration on how to create Standard C UEFI Shell applications, easily and quickly, +using the latest development environment from Microsoft and the *open source*, *monolithic*, *multi-target* +[**toro C Library**](https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library) + + +## Introduction +**Visual Studio 2022** is out now.
+ +In this blog I will introduce native Linux programers, kernel hackers, embedded firmware developers, +former MSDOS programers, teachers and students with a good grasp in C and last, +but not least, UEFI BIOS engineers to the easiest and fastest of creating native +Standard C programs for the UEFI Shell. + +This is not a beginners´ tutorial. You need to have an idea on how to use a C compiler and linker +in a command line environment, how I/O redirection works and how parameters are +passed to the C application and how to use the most frequently used Standard C functions +like `malloc()`, `printf()` and `scanf()`. + +Additionally you need an understanding of the I/O components on an IBM-AT compatible +UEFI platform. + +Nowadays C compilers have a lot of non-standard extensions in language, library and so called +*intrinsic* (called *built-in* in the GNU terminolgy) functions to meet platform and developer requirements. I mean I/O functions like +`outp()`/`inp()` family. Those functions will be used here. + +To follow the examples listed here please install **Visual Studio 2022** **"Desktop development with C++"** on your x64-Windows host. +https://github.com/KilianKegel/HowTo-setup-an-UEFI-Development-PC#howto-setup-an-uefi-development-pc + +## Starting **Visual Studio 2022** +**Visual Studio 2022** looks like this: +![VS2022CLI](VS2022CLI.png) + +It contains the C compiler `cl.exe`, the linker `link.exe`, the COFF/PE Dumper and disassembler `dumpbin.exe`, the library manager +`lib.exe`, the legacy make tool `nmake.exe`, the new build engine `msbuild.exe` and many, many others.
+I will focus on compiler, linker, disassembler and librarian only. + +To start this command line window, go to: +1. Start +2. Visual Studio 2022 +3. x64 Native Tools Command Prompt for VS2022 Current + +![VS2022CLIStart](VS2022CLIStart.png) + + +After starting the VS2022CLI (command line interface) go to your builddrive and type:
+`git clone --recursive --branch CdePkg https://github.com/tianocore/edk2-staging.git CdePkgBLOG202111` + +It will look similiar to this: +![repoclone](repoclone.png) + +Change into the `blogs\2021-11-14` folder by typing:
+`cd blogs\2021-11-14\lib`
+and type: `type WELCOME.c | find /n /v ""` to see what `WELCOME.c` truly is. +![welcomelist](welcomelist.png) + +It is a simple C99-Standard-compatible HelloWorld program, that +uses C99 `//`-style comments. + +## Using the compiler and linker +### Compiling the .C file +You can compile the sample WELCOME.c source module to its corresponding .OBJ module:
+`cl /nologo /c /GS- /D_NO_CRT_STDIO_INLINE /D_CRT_SECURE_NO_WARNINGS WELCOME.c` + +What does this mean?
+1. `cl` is the Microsoft C/C++ compiler +2. `/nologo` supresses the copyright message +3. `/c` only compiles, does not invoke LINK.EXE +4. `/GS-` disables stack checks, as in tianocore UEFI build settings +5. `/D_NO_CRT_STDIO_INLINE` a preprocessor defininition that forces the compiler to generate true `printf()` and `scanf()` function calls and to prevent from inlining these functions +6. `/D_CRT_SECURE_NO_WARNINGS` a preprocessor defininition that prevents from bothering about `*_s` secure counterpart +7. `WELCOME.c`is the source module + +### Linking the .OBJ module to an UEFI Application +You can link the sample WELCOME.OBJ module to its corresponding .EFI module:
+`link /nologo /NODEFAULTLIB /ENTRY:_cdeCRT0UefiShell /OUT:welcome.efi /SUBSYSTEM:EFI_APPLICATION /MAP:WELCOMEUefiShell.map WELCOME.obj toroC64.lib`
+1. `link` is the Microsoft linker +2. `/nologo` supresses the copyright message +3. `/NODEFAULTLIB` excludes all default libraries +4. `/ENTRY:_cdeCRT0UefiShell` the name of the particular `CRT0` (*C runtime 0*) function, that is the entry point in **toroC64.lib** +5. `/OUT:welcome.efi` the file name of the executable +6. `/SUBSYSTEM:EFI_APPLICATION` forces the linker to create a `EFI_APPLICATION` executable +7. `/MAP:WELCOMEUefiShell.map` the name of the .MAP file +8. `WELCOME.obj` the .OBJ module +9. `toroC64.lib` the only search library in uses during the link process + +It is easy to guess how WELCOME.efi's output would look like:
+ +![Welcome2AnsiCToroCLibUefiShell.png](Welcome2AnsiCToroCLibUefiShell.png) + +## Validating correctness / testing equivalence +But if you plan to create and validate a full-blown Standard C library for UEFI Shell and POST, +written from scratch, it would be helpful, if a major part of the test cases +* `printf()`/`scanf()` family format strings +* `malloc()`/`free()`/`realloc()` +* string and wide string handling functions +* file buffering etc. +* simply all functions listed here: https://github.com/KilianKegel/toro-C-Library/blob/master/implemented.md + +could be tested and debugged natively on the build machine, and need not to be copied to the UEFI target each time. + +NOTE: In early states of the **toro C Library** *construction bootstrap process* the `EmulatorPkg` +was deeply involved. But for UEFI-non-specific parts of the library, the multi-entrypoint feature +was used predominantly to debug natively on the build machine. + + +### Linking the .OBJ module to a Windows x64 command line Application +That could be easily done by linking `WELCOME.OBJ` to a Windows NT console executable
+`link /nologo /NODEFAULTLIB /ENTRY:_cdeCRT0WinNT /OUT:welcome.exe /SUBSYSTEM:CONSOLE /MAP:WELCOMEWinNT.map WELCOME.obj toroC64.lib kernel32.lib`
+ +Some parameters have changed:
+1. `/ENTRY:_cdeCRT0WinNT` `CRT0` for Windows NT executables in **toroC64.lib** +2. `/OUT:welcome.exe` the file name of the executable +3. `/SUBSYSTEM:CONSOLE` forces the linker to create a Windows NT executable +4. `/MAP:WELCOMEWinNT.map` the name of the .MAP file +5. `kernel32.lib` the import library to the Win32 API + +It is easy to guess how WELCOME.exe's output would look like:
+![Welcome2AnsiCToroCLibWinNT.png](Welcome2AnsiCToroCLibWinNT.png) + +### Linking the .OBJ module to a Windows x64 command line Application based on Microsoft LIBCMT.lib +If you still doubt, that WELCOME's `WELCOME, to ANSI C` written to the UEFI Shell and Windows text console +does not meet the Standard C format specification for `printf()`, just try to link the .OBJ module to the original Microsoft LIBCMT.lib, is not +suspicious to violate the C Standard generally:
+`link /nologo /OUT:welcomeMSFT.exe /SUBSYSTEM:CONSOLE /MAP:WELCOMEMsft.map WELCOME.obj kernel32.lib legacy_stdio_definitions.lib`
+ +Some parameters have changed:
+1. `/NODEFAULTLIB` is removed, since the default Microsoft LIBCMT.lib shall be bound to the .EXE +2. `/ENTRY` is not needed anymore, because LINK.EXE knows the name of the default `CRT0` +3. `/OUT:welcomeMSFT.exe` to mark the difference +4. `/MAP:WELCOMEMsft.map` the name of the .MAP file +4. `legacy_stdio_definitions.lib` an additional Microsoft library that includes functions that are not + provided anymore in LIBCMT.lib, but belong to Standard C. The linker finds that file in the default LIB search path. + +## Simple tools +Here I will demonstrate the early ports from my old MSDOS tools to UEFI.
+**NOTE: All the source files are in the root directory of this blog, and not in the `lib` +subdirectory.
+For LINK.EXE the path and name of the **toro C Library** is needed now `lib\toroC64.lib`** + +These tools all directly access hardware. Therefore UEFI specific header-files and EDK2 build +tools/engine are not needed. + +### rtcdmp - RTC dump tool +During legacy times it was often necessary to find out, what is in the +non-volatile / battery-bufferd RealTimeClock MC146818 chip, that still belongs +to the PC hardware architecture. It contains an alarm clock, that is still used +to wake the platform nowadays. And it contains additional battery buffered RAM (NVRAM), +about 112 bytes, that was used to store setup settings. + +Today only a small number of NVRAM is used, very platform dependant for scratch-pad usage +for memory detection purposes and so on. + +The century byte at offset 0x32 is still there. The first 16 bytes represent the data and +control registers of the clock circuitry. + +```c +[1] // +[2] // RTC dump tool +[3] // +[4] // Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +[5] // SPDX - License - Identifier: BSD-2-Clause-Patent +[6] // +[7] #include +[8] #include +[9] #include +[10] +[11] unsigned char getitem(int index) +[12] { +[13] //NOTE: "update in progress" is ignored +[14] outp(0x70, index); // write the index +[15] return (unsigned char)inp(0x71); // get the data +[16] } +[17] +[18] int main() +[19] { +[20] int i; +[21] +[22] for (i = 0; i < 128; i++) +[23] { +[24] int l; +[25] unsigned char linebuf[16]; +[26] +[27] if (0 == (i % 16)) // +[28] printf("%02X: ", i); // print the address +[29] linebuf[i % 16] = getitem(i); // get the value to a temporary line buffer +[30] printf("%02X ", linebuf[i % 16]); // print the value in hex format +[31] // +[32] if (0 == ((i + 1) % 8) // check mid of line +[33] && 0 != ((i + 1) % 16)) // +[34] printf("- "); // print the separator +[35] // +[36] if (0 == ((i + 1) % 16)) // check end of line +[37] { // +[38] printf(" "); // insert space after hex print, +[39] for (l = 0; l < 16; l++) // print ASCII representation +[40] printf("%c", isalnum(linebuf[l]) ? 0xFF & linebuf[l] : '.'); +[41] printf("\n"); // new line +[42] } +[43] } +[44] return EXIT_SUCCESS; +[45] } +``` +Compile and link:
+`cl /nologo /c /GS- /D_NO_CRT_STDIO_INLINE /D_CRT_SECURE_NO_WARNINGS rtcdmp.c`

+`link /nologo /NODEFAULTLIB /ENTRY:_cdeCRT0UefiShell /SUBSYSTEM:EFI_APPLICATION rtcdmp.obj lib\toroC64.lib`
+ +It looks like this:
+ +![rtcdmp.png](rtcdmp.png) + +### rtcwr - RTC write tool +Sometimes you need to alter a register/NVRAM byte in the RTC.
+`rtcwr 32 19` would change the century byte to 19 (because it is BCD encoded): + +```c +[1] // +[2] // RTC write tool +[3] // +[4] // Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +[5] // SPDX - License - Identifier: BSD-2-Clause-Patent +[6] // +[7] #include +[8] #include +[9] +[10] int setitem(int index, int data) +[11] { +[12] outp(0x70, index); +[13] outp(0x71, data); +[14] return 0; +[15] } +[16] +[17] int main(int argc, char** argv) +[18] { +[19] int index, data, t; +[20] +[21] if (argc < 3) { +[22] printf("ERROR: RTCwr missing parameter, use:\n RTCwr index value -- hex format\n"); +[23] exit(1); +[24] } +[25] +[26] t = sscanf(argv[1], "%x", &index); +[27] t = sscanf(argv[2], "%x", &data); +[28] // additionally the numbers of tokens scanned can be checked, ignored here +[29] +[30] setitem(index, data); +[31] +[32] } +``` +### iodmp - I/O dump tool +Quite often an UEFI engineer needs to know, if a particular I/O range or device +is enabled/disabled and the CPU I/O cycles truly reach the device. + +An IOdmp tool could be useful in such cases: [IOdmp.c](iodmp.c) + +### iowr - I/O write tool +Quite often an UEFI engineer needs to write to an I/O address. E.g. to +set COM1 (0x3F8 base) to 115200,n,8,1 and send a byte to an terminal program. +The command flow would look like that one:
+``` +iowr 3FB 83 +iowr 3F8 1 +iowr 3F9 0 +iowr 3FB 3 + +iowr 3F8 55 +``` + +This would send a "U" over the serial line. + +An IOwr tool could be useful in such cases: [IOwr.c](iowr.c) + +## My legacy toolbox +From now on it is an easy and repetitive task to adjust Dump and Write +tools for *memory*, *PCI* and *SuperIO* too. Additionally 16, 32 and 64bit (memory only) +access would be useful. + +Just invoke [**BUILD.bat**](build.bat) to create the .EFI applications from the files +listed below + +[iodmp.c ](iodmp.c), [iodmp16.c ](iodmp16.c), [iodmp32.c ](iodmp32.c),
+[iowr.c ](iowr.c), [iowr16.c ](iowr16.c), [iowr32.c ](iowr32.c),
+[memdmp.c ](memdmp.c), [memdmp16.c](memdmp16.c), [memdmp32.c](memdmp32.c), [memdmp64.c](memdmp64.c),
+[memwr.c ](memwr.c), [memwr16.c ](memwr16.c), [memwr32.c ](memwr32.c), [memwr64.c ](memwr64.c),
+[pcidmp.c ](pcidmp.c), [pcidmp16.c](pcidmp16.c), [pcidmp32.c](pcidmp32.c),
+[pciwr.c ](pciwr.c), [pciwr16.c ](pciwr16.c), [pciwr32.c ](pciwr32.c),
+[rtcdmp.c ](rtcdmp.c),
+[rtcwr.c ](rtcwr.c),
+[siodmp.c ](siodmp.c)
+ + +## Coming up soon... +1. 2021-11-28:
+ * Using UEFI- and Standard-C-API in shell applications
+ * Creating MSDOS tools.
+2. 2021-12-12:
+ * Adopting open source Visual-Studio projects to UEFI
+ * Introduction of the ACPCIA port to UEFI
+3. 2022-09-01:
+ * Introduction of how to calibrate a TSC-based software timer - on IBM-AT compatible UEFI platforms + diff --git a/blogs/2021-11-14/VS2022CLI.png b/blogs/2021-11-14/VS2022CLI.png new file mode 100644 index 00000000000..90b4135f23d Binary files /dev/null and b/blogs/2021-11-14/VS2022CLI.png differ diff --git a/blogs/2021-11-14/VS2022CLIStart.png b/blogs/2021-11-14/VS2022CLIStart.png new file mode 100644 index 00000000000..78eecfcbfdd Binary files /dev/null and b/blogs/2021-11-14/VS2022CLIStart.png differ diff --git a/blogs/2021-11-14/VS2022GUI.png b/blogs/2021-11-14/VS2022GUI.png new file mode 100644 index 00000000000..837630d215c Binary files /dev/null and b/blogs/2021-11-14/VS2022GUI.png differ diff --git a/blogs/2021-11-14/VS2022GUIStart.png b/blogs/2021-11-14/VS2022GUIStart.png new file mode 100644 index 00000000000..7a8d6813b06 Binary files /dev/null and b/blogs/2021-11-14/VS2022GUIStart.png differ diff --git a/blogs/2021-11-14/Welcome2AnsiCLinux.png b/blogs/2021-11-14/Welcome2AnsiCLinux.png new file mode 100644 index 00000000000..460949c7bca Binary files /dev/null and b/blogs/2021-11-14/Welcome2AnsiCLinux.png differ diff --git a/blogs/2021-11-14/Welcome2AnsiCToroCLibUefiShell.png b/blogs/2021-11-14/Welcome2AnsiCToroCLibUefiShell.png new file mode 100644 index 00000000000..817030a3488 Binary files /dev/null and b/blogs/2021-11-14/Welcome2AnsiCToroCLibUefiShell.png differ diff --git a/blogs/2021-11-14/Welcome2AnsiCToroCLibWinNT.png b/blogs/2021-11-14/Welcome2AnsiCToroCLibWinNT.png new file mode 100644 index 00000000000..7a53aa33b3d Binary files /dev/null and b/blogs/2021-11-14/Welcome2AnsiCToroCLibWinNT.png differ diff --git a/blogs/2021-11-14/Welcome2AnsiCwithoutCRLinux.png b/blogs/2021-11-14/Welcome2AnsiCwithoutCRLinux.png new file mode 100644 index 00000000000..5b53e536dd0 Binary files /dev/null and b/blogs/2021-11-14/Welcome2AnsiCwithoutCRLinux.png differ diff --git a/blogs/2021-11-14/Welcome2AnsiCwithoutCRUefiShell.png b/blogs/2021-11-14/Welcome2AnsiCwithoutCRUefiShell.png new file mode 100644 index 00000000000..0033e42b957 Binary files /dev/null and b/blogs/2021-11-14/Welcome2AnsiCwithoutCRUefiShell.png differ diff --git a/blogs/2021-11-14/Welcome2AnsiCwithoutCRWinNT.png b/blogs/2021-11-14/Welcome2AnsiCwithoutCRWinNT.png new file mode 100644 index 00000000000..58a50fea807 Binary files /dev/null and b/blogs/2021-11-14/Welcome2AnsiCwithoutCRWinNT.png differ diff --git a/blogs/2021-11-14/build.bat b/blogs/2021-11-14/build.bat new file mode 100644 index 00000000000..393bcc6a1e6 --- /dev/null +++ b/blogs/2021-11-14/build.bat @@ -0,0 +1,18 @@ +@echo off +SET BUILDSTART=%TIME% +if /I "%1" == "/clean" ( + if exist *.obj del *.obj > NUL + if exist *.efi del *.efi > NUL + goto EOF +) +echo compling... +cl /nologo /W4 /c /GS- /D_NO_CRT_STDIO_INLINE /D_CRT_SECURE_NO_WARNINGS *.c +for %%o in (*.obj) do ( + echo linking %%~no.efi + link /nologo /NODEFAULTLIB /ENTRY:_cdeCRT0UefiShell /SUBSYSTEM:EFI_APPLICATION %%~no lib\toroC64.lib +) +echo. +echo BuildStart: %BUILDSTART% +echo BuildEnd: %TIME% +echo. +:EOF diff --git a/blogs/2021-11-14/iodmp.c b/blogs/2021-11-14/iodmp.c new file mode 100644 index 00000000000..7720158417b --- /dev/null +++ b/blogs/2021-11-14/iodmp.c @@ -0,0 +1,63 @@ +// +// I/O dump tool +// +#include +#include +#include + +#define FMTSTR "%02X "/*char*/ +#define TYPE char +#define ITEMSIZE sizeof(TYPE) +#define ITEMS_PER_LINE (16 / ITEMSIZE) +#define ITEM_MASK ((1LL << (8 * ITEMSIZE))-1) + +int getitem(int index) +{ + //NOTE: "update in progress" is ignored + return inp(index); // get the data +} + +int main(int argc, char **argv) +{ + int i, start, num, t; + + if (argc < 3) { + printf("ERROR: IOdmp missing parameter, use:\n IOdmp start num -- hex format\n"); + exit(EXIT_FAILURE); + } + + t = sscanf(argv[1], "%x", &start); + t = sscanf(argv[2], "%x", &num); + // additionally the numbers of tokens scanned can be checked, ignored here + + for (i = 0; i < num / ITEMSIZE; i++) + { + int l/*ine*/, r/*everse*/; + int linebuf[ITEMS_PER_LINE]; + + if (0 == (i % ITEMS_PER_LINE)) // + printf("%04zX: ", start + i * ITEMSIZE); // print the address + linebuf[i % ITEMS_PER_LINE] = getitem(start + i * ITEMSIZE); // get the value to a temporary line buffer + printf(FMTSTR, (int)(ITEM_MASK & linebuf[i % ITEMS_PER_LINE])); // print the value in hex format + // + if (0 == ((i + 1) % (ITEMS_PER_LINE / 2)) // check mid of line + && 0 != ((i + 1) % ITEMS_PER_LINE)) // + printf("- "); // print the separator + // + if (0 == ((i + 1) % ITEMS_PER_LINE)) // check end of line + { // + printf(" "); // insert space after hex print, + for (l = 0; l < ITEMS_PER_LINE; l++) // print ASCII representation + { // + for (r = ITEMSIZE * 8 - 8; r >= 0; r -= sizeof(char) * 8) // + { // + int v = linebuf[l] >> r; // + printf("%c", isalnum(0xFF & v) ? 0xFF & v : '.'); // + } // + printf(ITEMSIZE > 1 ? " " : ""); // + } // + printf("\n"); // new line + } + } + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/blogs/2021-11-14/iodmp16.c b/blogs/2021-11-14/iodmp16.c new file mode 100644 index 00000000000..29c61f60e56 --- /dev/null +++ b/blogs/2021-11-14/iodmp16.c @@ -0,0 +1,63 @@ +// +// I/O dump 16 tool +// +#include +#include +#include + +#define FMTSTR "%04X "/*char*/ +#define TYPE short +#define ITEMSIZE sizeof(TYPE) +#define ITEMS_PER_LINE (16 / ITEMSIZE) +#define ITEM_MASK ((1LL << (8 * ITEMSIZE))-1) + +int getitem(int index) +{ + //NOTE: "update in progress" is ignored + return inpw(index); // get the data +} + +int main(int argc, char **argv) +{ + int i, start, num, t; + + if (argc < 3) { + printf("ERROR: IOdmp16 missing parameter, use:\n IOdmp16 start numbytes -- hex format\n"); + exit(EXIT_FAILURE); + } + + t = sscanf(argv[1], "%x", &start); + t = sscanf(argv[2], "%x", &num); + // additionally the numbers of tokens scanned can be checked, ignored here + + for (i = 0; i < num / ITEMSIZE; i++) + { + int l/*ine*/, r/*everse*/; + int linebuf[ITEMS_PER_LINE]; + + if (0 == (i % ITEMS_PER_LINE)) // + printf("%04zX: ", start + i * ITEMSIZE); // print the address + linebuf[i % ITEMS_PER_LINE] = getitem(start + i * ITEMSIZE); // get the value to a temporary line buffer + printf(FMTSTR, (int)(ITEM_MASK & linebuf[i % ITEMS_PER_LINE])); // print the value in hex format + // + if (0 == ((i + 1) % (ITEMS_PER_LINE / 2)) // check mid of line + && 0 != ((i + 1) % ITEMS_PER_LINE)) // + printf("- "); // print the separator + // + if (0 == ((i + 1) % ITEMS_PER_LINE)) // check end of line + { // + printf(" "); // insert space after hex print, + for (l = 0; l < ITEMS_PER_LINE; l++) // print ASCII representation + { // + for (r = ITEMSIZE * 8 - 8; r >= 0; r -= sizeof(char) * 8) // + { // + int v = linebuf[l] >> r; // + printf("%c", isalnum(0xFF & v) ? 0xFF & v : '.'); // + } // + printf(ITEMSIZE > 1 ? " " : ""); // + } // + printf("\n"); // new line + } + } + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/blogs/2021-11-14/iodmp32.c b/blogs/2021-11-14/iodmp32.c new file mode 100644 index 00000000000..eece7c858ec --- /dev/null +++ b/blogs/2021-11-14/iodmp32.c @@ -0,0 +1,63 @@ +// +// I/O dump 32 tool +// +#include +#include +#include + +#define FMTSTR "%08X "/*char*/ +#define TYPE int +#define ITEMSIZE sizeof(TYPE) +#define ITEMS_PER_LINE (16 / ITEMSIZE) +#define ITEM_MASK ((1LL << (8 * ITEMSIZE))-1) + +int getitem(int index) +{ + //NOTE: "update in progress" is ignored + return inpd(index); // get the data +} + +int main(int argc, char **argv) +{ + int i, start, num, t; + + if (argc < 3) { + printf("ERROR: IOdmp32 missing parameter, use:\n IOdmp32 start numbytes -- hex format\n"); + exit(EXIT_FAILURE); + } + + t = sscanf(argv[1], "%x", &start); + t = sscanf(argv[2], "%x", &num); + // additionally the numbers of tokens scanned can be checked, ignored here + + for (i = 0; i < num/ITEMSIZE; i++ ) + { + int l/*ine*/, r/*everse*/; + int linebuf[ITEMS_PER_LINE]; + + if (0 == (i % ITEMS_PER_LINE)) // + printf("%04zX: ", start + i * ITEMSIZE); // print the address + linebuf[i % ITEMS_PER_LINE] = getitem(start + i * ITEMSIZE); // get the value to a temporary line buffer + printf(FMTSTR, (int)(ITEM_MASK & linebuf[i % ITEMS_PER_LINE])); // print the value in hex format + // + if (0 == ((i + 1) % (ITEMS_PER_LINE/2)) // check mid of line + && 0 != ((i + 1) % ITEMS_PER_LINE)) // + printf("- "); // print the separator + // + if (0 == ((i + 1) % ITEMS_PER_LINE)) // check end of line + { // + printf(" "); // insert space after hex print, + for (l = 0; l < ITEMS_PER_LINE; l++) // print ASCII representation + { // + for (r = ITEMSIZE * 8 - 8; r >= 0; r -= sizeof(char) * 8) // + { // + int v = linebuf[l] >> r; // + printf("%c", isalnum(0xFF & v) ? 0xFF & v : '.'); // + } // + printf(ITEMSIZE > 1 ? " " : ""); // + } // + printf("\n"); // new line + } + } + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/blogs/2021-11-14/iowr.c b/blogs/2021-11-14/iowr.c new file mode 100644 index 00000000000..6356f1a2074 --- /dev/null +++ b/blogs/2021-11-14/iowr.c @@ -0,0 +1,28 @@ +// +// I/O write tool +// +#include +#include + +int setitem(int port, int data) +{ + outp(port, data); + return 0; +} + +int main(int argc, char** argv) +{ + int port, data, t; + + if (argc < 3) { + printf("ERROR: IOwr missing parameter, use:\n IOwr portx value -- hex format\n"); + exit(1); + } + + t = sscanf(argv[1], "%x", &port); + t = sscanf(argv[2], "%x", &data); + // additionally the numbers of tokens scanned can be checked, ignored here + + setitem(port, data); + +} \ No newline at end of file diff --git a/blogs/2021-11-14/iowr16.c b/blogs/2021-11-14/iowr16.c new file mode 100644 index 00000000000..6d72ff777b9 --- /dev/null +++ b/blogs/2021-11-14/iowr16.c @@ -0,0 +1,28 @@ +// +// I/O write 16 tool +// +#include +#include + +int setitem(int port, int data) +{ + outpw(port, data); + return 0; +} + +int main(int argc, char** argv) +{ + int port, data, t; + + if (argc < 3) { + printf("ERROR: IOwr16 missing parameter, use:\n IOwr16 portx value -- hex format\n"); + exit(1); + } + + t = sscanf(argv[1], "%x", &port); + t = sscanf(argv[2], "%x", &data); + // additionally the numbers of tokens scanned can be checked, ignored here + + setitem(port, data); + +} \ No newline at end of file diff --git a/blogs/2021-11-14/iowr32.c b/blogs/2021-11-14/iowr32.c new file mode 100644 index 00000000000..a0afe5ab0c2 --- /dev/null +++ b/blogs/2021-11-14/iowr32.c @@ -0,0 +1,28 @@ +// +// I/O write 32 tool +// +#include +#include + +int setitem(int port, int data) +{ + outpd(port, data); + return 0; +} + +int main(int argc, char** argv) +{ + int port, data, t; + + if (argc < 3) { + printf("ERROR: IOwr32 missing parameter, use:\n IOwr32 portx value -- hex format\n"); + exit(1); + } + + t = sscanf(argv[1], "%x", &port); + t = sscanf(argv[2], "%x", &data); + // additionally the numbers of tokens scanned can be checked, ignored here + + setitem(port, data); + +} \ No newline at end of file diff --git a/blogs/2021-11-14/lib b/blogs/2021-11-14/lib new file mode 160000 index 00000000000..2d4af8547f4 --- /dev/null +++ b/blogs/2021-11-14/lib @@ -0,0 +1 @@ +Subproject commit 2d4af8547f4a0df8cdbe0cf100df856d92d106ad diff --git a/blogs/2021-11-14/memdmp.c b/blogs/2021-11-14/memdmp.c new file mode 100644 index 00000000000..9cbe2f78dbb --- /dev/null +++ b/blogs/2021-11-14/memdmp.c @@ -0,0 +1,67 @@ +// +// MEM dump tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include +#include + +#define FMTSTR "%02X "/*char*/ +#define TYPE char +#define ITEMSIZE sizeof(TYPE) +#define ITEMS_PER_LINE (16 / ITEMSIZE) +#define ITEM_MASK ((1LL << (8 * ITEMSIZE))-1) + +int getitem(intptr_t addr) +{ + char* p = (char*)addr; + return *p; // get the data +} + +int main(int argc, char **argv) +{ + int i, num, t; + intptr_t start; + + if (argc < 3) { + printf("ERROR: MEMdmp missing parameter, use:\n MEMdmp start numbytes -- hex format\n"); + exit(EXIT_FAILURE); + } + + t = sscanf(argv[1], "%llx", &start); + t = sscanf(argv[2], "%x", &num); + // additionally the numbers of tokens scanned can be checked, ignored here + + for (i = 0; i < num/ITEMSIZE; i++ ) + { + int l/*ine*/, r/*everse*/; + int linebuf[ITEMS_PER_LINE]; + + if (0 == (i % ITEMS_PER_LINE)) // + printf("%016zX: ", start + i * ITEMSIZE); // print the address + linebuf[i % ITEMS_PER_LINE] = getitem(start + i * ITEMSIZE);// get the value to a temporary line buffer + printf(FMTSTR, (int)(ITEM_MASK & linebuf[i % ITEMS_PER_LINE])); // print the value in hex format + // + if (0 == ((i + 1) % (ITEMS_PER_LINE/2)) // check mid of line + && 0 != ((i + 1) % ITEMS_PER_LINE)) // + printf("- "); // print the separator + // + if (0 == ((i + 1) % ITEMS_PER_LINE)) // check end of line + { // + printf(" "); // insert space after hex print, + for (l = 0; l < ITEMS_PER_LINE; l++) // print ASCII representation + { // + for (r = ITEMSIZE * 8 - 8; r >= 0; r -= sizeof(char) * 8) + { // + int v = linebuf[l] >> r; // + printf("%c", isalnum(0xFF & v) ? 0xFF & v : '.'); + } // + printf(ITEMSIZE > 1 ? " " : ""); // + } // + printf("\n"); // new line + } + } + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/blogs/2021-11-14/memdmp16.c b/blogs/2021-11-14/memdmp16.c new file mode 100644 index 00000000000..a84f46facc6 --- /dev/null +++ b/blogs/2021-11-14/memdmp16.c @@ -0,0 +1,64 @@ +// +// MEM dump tool +// +#include +#include +#include + +#define FMTSTR "%04X "/*short*/ +#define TYPE short +#define ITEMSIZE sizeof(TYPE) +#define ITEMS_PER_LINE (16 / ITEMSIZE) +#define ITEM_MASK ((1LL << (8 * ITEMSIZE))-1) + +int getitem(intptr_t addr) +{ + TYPE* p = (TYPE*)addr; + return *p; // get the data +} + +int main(int argc, char **argv) +{ + int i, num, t; + intptr_t start; + + if (argc < 3) { + printf("ERROR: MEMdmp missing parameter, use:\n MEMdmp start numbytes -- hex format\n"); + exit(EXIT_FAILURE); + } + + t = sscanf(argv[1], "%llx", &start); + t = sscanf(argv[2], "%x", &num); + // additionally the numbers of tokens scanned can be checked, ignored here + + for (i = 0; i < num/ITEMSIZE; i++ ) + { + int l/*ine*/, r/*everse*/; + int linebuf[ITEMS_PER_LINE]; + + if (0 == (i % ITEMS_PER_LINE)) // + printf("%016zX: ", start + i * ITEMSIZE); // print the address + linebuf[i % ITEMS_PER_LINE] = getitem(start + i * ITEMSIZE);// get the value to a temporary line buffer + printf(FMTSTR, (int)(ITEM_MASK & linebuf[i % ITEMS_PER_LINE])); // print the value in hex format + // + if (0 == ((i + 1) % (ITEMS_PER_LINE/2)) // check mid of line + && 0 != ((i + 1) % ITEMS_PER_LINE)) // + printf("- "); // print the separator + // + if (0 == ((i + 1) % ITEMS_PER_LINE)) // check end of line + { // + printf(" "); // insert space after hex print, + for (l = 0; l < ITEMS_PER_LINE; l++) // print ASCII representation + { // + for (r = ITEMSIZE * 8 - 8; r >= 0; r -= sizeof(char) * 8) + { // + int v = linebuf[l] >> r; // + printf("%c", isalnum(0xFF & v) ? 0xFF & v : '.'); + } // + printf(ITEMSIZE > 1 ? " " : ""); // + } // + printf("\n"); // new line + } + } + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/blogs/2021-11-14/memdmp32.c b/blogs/2021-11-14/memdmp32.c new file mode 100644 index 00000000000..64385102afb --- /dev/null +++ b/blogs/2021-11-14/memdmp32.c @@ -0,0 +1,67 @@ +// +// MEM dump 32 tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include +#include + +#define FMTSTR "%08X "/*int*/ +#define TYPE int +#define ITEMSIZE sizeof(TYPE) +#define ITEMS_PER_LINE (16 / ITEMSIZE) +#define ITEM_MASK ((1LL << (8 * ITEMSIZE))-1) + +int getitem(intptr_t addr) +{ + TYPE* p = (TYPE*)addr; + return *p; // get the data +} + +int main(int argc, char **argv) +{ + int i, num, t; + intptr_t start; + + if (argc < 3) { + printf("ERROR: MEMdmp missing parameter, use:\n MEMdmp start numbytes -- hex format\n"); + exit(EXIT_FAILURE); + } + + t = sscanf(argv[1], "%llx", &start); + t = sscanf(argv[2], "%x", &num); + // additionally the numbers of tokens scanned can be checked, ignored here + + for (i = 0; i < num/ITEMSIZE; i++ ) + { + int l/*ine*/, r/*everse*/; + int linebuf[ITEMS_PER_LINE]; + + if (0 == (i % ITEMS_PER_LINE)) // + printf("%016zX: ", start + i * ITEMSIZE); // print the address + linebuf[i % ITEMS_PER_LINE] = getitem(start + i * ITEMSIZE);// get the value to a temporary line buffer + printf(FMTSTR, (int)(ITEM_MASK & linebuf[i % ITEMS_PER_LINE])); // print the value in hex format + // + if (0 == ((i + 1) % (ITEMS_PER_LINE/2)) // check mid of line + && 0 != ((i + 1) % ITEMS_PER_LINE)) // + printf("- "); // print the separator + // + if (0 == ((i + 1) % ITEMS_PER_LINE)) // check end of line + { // + printf(" "); // insert space after hex print, + for (l = 0; l < ITEMS_PER_LINE; l++) // print ASCII representation + { // + for (r = ITEMSIZE * 8 - 8; r >= 0; r -= sizeof(char) * 8) + { // + int v = linebuf[l] >> r; // + printf("%c", isalnum(0xFF & v) ? 0xFF & v : '.'); + } // + printf(ITEMSIZE > 1 ? " " : ""); // + } // + printf("\n"); // new line + } + } + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/blogs/2021-11-14/memdmp64.c b/blogs/2021-11-14/memdmp64.c new file mode 100644 index 00000000000..ea0542bb4fa --- /dev/null +++ b/blogs/2021-11-14/memdmp64.c @@ -0,0 +1,67 @@ +// +// MEM dump 32 tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include +#include + +#define FMTSTR "%016llX "/*long long*/ +#define TYPE long long +#define ITEMSIZE sizeof(TYPE) +#define ITEMS_PER_LINE (16 / ITEMSIZE) +#define ITEM_MASK (0xFFFFFFFFFFFFFFFFLL) + +long long getitem(intptr_t addr) +{ + TYPE* p = (TYPE*)addr; + return *p; // get the data +} + +int main(int argc, char **argv) +{ + int i, num, t; + intptr_t start; + + if (argc < 3) { + printf("ERROR: MEMdmp missing parameter, use:\n MEMdmp start numbytes -- hex format\n"); + exit(EXIT_FAILURE); + } + + t = sscanf(argv[1], "%llx", &start); + t = sscanf(argv[2], "%x", &num); + // additionally the numbers of tokens scanned can be checked, ignored here + + for (i = 0; i < num/ITEMSIZE; i++ ) + { + int l/*ine*/, r/*everse*/; + long long linebuf[ITEMS_PER_LINE]; + + if (0 == (i % ITEMS_PER_LINE)) // + printf("%016zX: ", start + i * ITEMSIZE); // print the address + linebuf[i % ITEMS_PER_LINE] = getitem(start + i * ITEMSIZE);// get the value to a temporary line buffer + printf(FMTSTR, (long long)(ITEM_MASK & linebuf[i % ITEMS_PER_LINE])); // print the value in hex format + // + if (0 == ((i + 1) % (ITEMS_PER_LINE/2)) // check mid of line + && 0 != ((i + 1) % ITEMS_PER_LINE)) // + printf("- "); // print the separator + // + if (0 == ((i + 1) % ITEMS_PER_LINE)) // check end of line + { // + printf(" "); // insert space after hex print, + for (l = 0; l < ITEMS_PER_LINE; l++) // print ASCII representation + { // + for (r = ITEMSIZE * 8 - 8; r >= 0; r -= sizeof(char) * 8) + { // + long long v = linebuf[l] >> r; // + printf("%c", isalnum(0xFF & v) ? (int)(0xFFLL & v) : '.'); + } // + printf(ITEMSIZE > 1 ? " " : ""); // + } // + printf("\n"); // new line + } + } + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/blogs/2021-11-14/memwr.c b/blogs/2021-11-14/memwr.c new file mode 100644 index 00000000000..5ac6f839cb6 --- /dev/null +++ b/blogs/2021-11-14/memwr.c @@ -0,0 +1,33 @@ +// +// MEM write tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include + +int setitem(intptr_t addr, int data) +{ + char* p = (char*)addr; + *p = (char)data; + return 0; +} + +int main(int argc, char** argv) +{ + int data, t; + intptr_t addr; + + if (argc < 3) { + printf("ERROR: MEMwr missing parameter, use:\n MEMwr portx value -- hex format\n"); + exit(1); + } + + t = sscanf(argv[1], "%llx", &addr); + t = sscanf(argv[2], "%x", &data); + // additionally the numbers of tokens scanned can be checked, ignored here + + setitem(addr, data); + +} \ No newline at end of file diff --git a/blogs/2021-11-14/memwr16.c b/blogs/2021-11-14/memwr16.c new file mode 100644 index 00000000000..c39cf1088f6 --- /dev/null +++ b/blogs/2021-11-14/memwr16.c @@ -0,0 +1,33 @@ +// +// MEM write 16 tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include + +int setitem(intptr_t addr, int data) +{ + short* p = (short*)addr; + *p = (short)data; + return 0; +} + +int main(int argc, char** argv) +{ + int data, t; + intptr_t addr; + + if (argc < 3) { + printf("ERROR: MEMwr16 missing parameter, use:\n MEMwr16 portx value -- hex format\n"); + exit(1); + } + + t = sscanf(argv[1], "%llx", &addr); + t = sscanf(argv[2], "%x", &data); + // additionally the numbers of tokens scanned can be checked, ignored here + + setitem(addr, data); + +} \ No newline at end of file diff --git a/blogs/2021-11-14/memwr32.c b/blogs/2021-11-14/memwr32.c new file mode 100644 index 00000000000..a4920b98068 --- /dev/null +++ b/blogs/2021-11-14/memwr32.c @@ -0,0 +1,33 @@ +// +// MEM write 32 tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include + +int setitem(intptr_t addr, int data) +{ + int* p = (int*)addr; + *p = data; + return 0; +} + +int main(int argc, char** argv) +{ + int data, t; + intptr_t addr; + + if (argc < 3) { + printf("ERROR: MEMwr32 missing parameter, use:\n MEMwr32 portx value -- hex format\n"); + exit(1); + } + + t = sscanf(argv[1], "%llx", &addr); + t = sscanf(argv[2], "%x", &data); + // additionally the numbers of tokens scanned can be checked, ignored here + + setitem(addr, data); + +} \ No newline at end of file diff --git a/blogs/2021-11-14/memwr64.c b/blogs/2021-11-14/memwr64.c new file mode 100644 index 00000000000..3792975c8a9 --- /dev/null +++ b/blogs/2021-11-14/memwr64.c @@ -0,0 +1,34 @@ +// +// MEM write 64 tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include + +int setitem(intptr_t addr, long long data) +{ + long long* p = (long long*)addr; + *p = (long long)data; + return 0; +} + +int main(int argc, char** argv) +{ + int t; + long long data; + intptr_t addr; + + if (argc < 3) { + printf("ERROR: MEMwr16 missing parameter, use:\n MEMwr16 portx value -- hex format\n"); + exit(1); + } + + t = sscanf(argv[1], "%llx", &addr); + t = sscanf(argv[2], "%llx", &data); + // additionally the numbers of tokens scanned can be checked, ignored here + + setitem(addr, data); + +} \ No newline at end of file diff --git a/blogs/2021-11-14/pcidmp.c b/blogs/2021-11-14/pcidmp.c new file mode 100644 index 00000000000..cf0d55fe126 --- /dev/null +++ b/blogs/2021-11-14/pcidmp.c @@ -0,0 +1,96 @@ +// +// PCI dump tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include +#include +#include + +#define FMTSTR "%02X "/*char*/ +#define TYPE char +#define ITEMSIZE sizeof(TYPE) +#define ITEMS_PER_LINE (16 / ITEMSIZE) +#define ITEM_MASK ((1LL << (8 * ITEMSIZE))-1) + +int getitem(int bus, int dev, int fun, int reg) +{ + outpd(0xCF8, 0x80000000 + (bus << 16) + (dev << 11) + (fun << 8) + (reg & ~3)); + return (TYPE)inp(0xCFC + (3 & reg)); +} + +void dumpdev(int bus, int dev, int fun) +{ + int i, num = 256; + + printf("PCI bus %x dev %x fun %x\n", bus, dev, fun); + + for (i = 0; i < num / ITEMSIZE; i++) + { + int l/*ine*/, r/*everse*/; + int linebuf[ITEMS_PER_LINE]; + + if (0 == (i % ITEMS_PER_LINE)) // + printf("%04zX: ", i * ITEMSIZE); // print the address + linebuf[i % ITEMS_PER_LINE] = getitem(bus, dev, fun, i * ITEMSIZE); // get the value to a temporary line buffer + printf(FMTSTR, (int)(ITEM_MASK & linebuf[i % ITEMS_PER_LINE])); // print the value in hex format + // + if (0 == ((i + 1) % (ITEMS_PER_LINE / 2)) // check mid of line + && 0 != ((i + 1) % ITEMS_PER_LINE)) // + printf("- "); // print the separator + // + if (0 == ((i + 1) % ITEMS_PER_LINE)) // check end of line + { // + printf(" "); // insert space after hex print, + for (l = 0; l < ITEMS_PER_LINE; l++) // print ASCII representation + { // + for (r = ITEMSIZE * 8 - 8; r >= 0; r -= sizeof(char) * 8) // + { // + int v = linebuf[l] >> r; // + printf("%c", isalnum(0xFF & v) ? 0xFF & v : '.'); // + } // + printf(ITEMSIZE > 1 ? " " : ""); // + } // + printf("\n"); // new line + } + } +} + +int main(int argc, char** argv) +{ + int t, bus, dev, fun, headertype, vendev; + + if (argc < 4 && 0 != strcmp("/all", argv[1])) { + printf("ERROR: PCIdmp missing parameter, use:\n PCIdmp bus dev fun -- hex format\n PCIdmp /all\n"); + exit(EXIT_FAILURE); + } + + if (0 == strcmp(argv[1], "/all")) { + for (bus = 0; bus < 256; bus++) // scan all busses ... + for (dev = 0; dev < 32; dev++) // ...all devices on each bus.. + for (fun = 0; fun < 8; fun++) { // ...and all functions on each device + vendev = getitem(bus, dev, fun, 0); // get vendor/device ID from offest 0 + if (-1 == vendev) // continue when no device found (0xFFFFFFFF) + continue; // + // + dumpdev(bus, dev, fun); // dump the entire PCI header + // + headertype = getitem(bus, dev, fun, 0xC); // check header type ... + headertype >>= 16; // + if (fun == 0 && !(headertype & 0x80/*multi fun bit*/)) // ... if function 0 to be a multifuction device + break;//for(fun = 0 ; fun < 8 ; fun ++) // ... continue with next device if not + } + } + else { + t = sscanf(argv[1], "%x", &bus); + t = sscanf(argv[2], "%x", &dev); + t = sscanf(argv[3], "%x", &fun); + // additionally the numbers of tokens scanned can be checked, ignored here + + dumpdev(bus, dev, fun); // dump the entire PCI header + } + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/blogs/2021-11-14/pcidmp16.c b/blogs/2021-11-14/pcidmp16.c new file mode 100644 index 00000000000..b85aa72d0b3 --- /dev/null +++ b/blogs/2021-11-14/pcidmp16.c @@ -0,0 +1,96 @@ +// +// PCI dump 16 tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include +#include +#include + +#define FMTSTR "%04X "/*short*/ +#define TYPE short +#define ITEMSIZE sizeof(TYPE) +#define ITEMS_PER_LINE (16 / ITEMSIZE) +#define ITEM_MASK ((1LL << (8 * ITEMSIZE))-1) + +int getitem(int bus, int dev, int fun, int reg) +{ + outpd(0xCF8, 0x80000000 + (bus << 16) + (dev << 11) + (fun << 8) + (reg & ~3)); + return (TYPE)inpw(0xCFC + (3 & reg)); +} + +void dumpdev(int bus, int dev, int fun) +{ + int i, num = 256; + + printf("PCI bus %x dev %x fun %x\n", bus, dev, fun); + + for (i = 0; i < num / ITEMSIZE; i++) + { + int l/*ine*/, r/*everse*/; + int linebuf[ITEMS_PER_LINE]; + + if (0 == (i % ITEMS_PER_LINE)) // + printf("%04zX: ", i * ITEMSIZE); // print the address + linebuf[i % ITEMS_PER_LINE] = getitem(bus, dev, fun, i * ITEMSIZE); // get the value to a temporary line buffer + printf(FMTSTR, (int)(ITEM_MASK & linebuf[i % ITEMS_PER_LINE])); // print the value in hex format + // + if (0 == ((i + 1) % (ITEMS_PER_LINE / 2)) // check mid of line + && 0 != ((i + 1) % ITEMS_PER_LINE)) // + printf("- "); // print the separator + // + if (0 == ((i + 1) % ITEMS_PER_LINE)) // check end of line + { // + printf(" "); // insert space after hex print, + for (l = 0; l < ITEMS_PER_LINE; l++) // print ASCII representation + { // + for (r = ITEMSIZE * 8 - 8; r >= 0; r -= sizeof(char) * 8) // + { // + int v = linebuf[l] >> r; // + printf("%c", isalnum(0xFF & v) ? 0xFF & v : '.'); // + } // + printf(ITEMSIZE > 1 ? " " : ""); // + } // + printf("\n"); // new line + } + } +} + +int main(int argc, char **argv) +{ + int t, bus, dev, fun, headertype, vendev; + + if (argc < 4 && 0 != strcmp("/all", argv[1])) { + printf("ERROR: PCIdmp16 missing parameter, use:\n PCIdmp16 bus dev fun -- hex format\n PCIdmp16 /all\n"); + exit(EXIT_FAILURE); + } + + if (0 == strcmp(argv[1], "/all")) { + for (bus = 0; bus < 256; bus++) // scan all busses ... + for (dev = 0; dev < 32; dev++) // ...all devices on each bus.. + for (fun = 0; fun < 8; fun++) { // ...and all functions on each device + vendev = getitem(bus, dev, fun, 0); // get vendor/device ID from offest 0 + if (-1 == vendev) // continue when no device found (0xFFFFFFFF) + continue; // + // + dumpdev(bus, dev, fun); // dump the entire PCI header + // + headertype = getitem(bus, dev, fun, 0xC); // check header type ... + headertype >>= 16; // + if (fun == 0 && !(headertype & 0x80/*multi fun bit*/)) // ... if function 0 to be a multifuction device + break;//for(fun = 0 ; fun < 8 ; fun ++) // ... continue with next device if not + } + } + else { + t = sscanf(argv[1], "%x", &bus); + t = sscanf(argv[2], "%x", &dev); + t = sscanf(argv[3], "%x", &fun); + // additionally the numbers of tokens scanned can be checked, ignored here + + dumpdev(bus, dev, fun); // dump the entire PCI header + } + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/blogs/2021-11-14/pcidmp32.c b/blogs/2021-11-14/pcidmp32.c new file mode 100644 index 00000000000..a41cd62aa3b --- /dev/null +++ b/blogs/2021-11-14/pcidmp32.c @@ -0,0 +1,96 @@ +// +// PCI dump 32 tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include +#include +#include + +#define FMTSTR "%08X "/*int*/ +#define TYPE int +#define ITEMSIZE sizeof(TYPE) +#define ITEMS_PER_LINE (16 / ITEMSIZE) +#define ITEM_MASK ((1LL << (8 * ITEMSIZE))-1) + +int getitem(int bus, int dev, int fun, int reg) +{ + outpd(0xCF8, 0x80000000 + (bus << 16) + (dev << 11) + (fun << 8) + (reg & ~3)); + return (TYPE)inpd(0xCFC + (3 & reg)); +} + +void dumpdev(int bus, int dev, int fun) +{ + int i, num = 256; + + printf("PCI bus %x dev %x fun %x\n", bus, dev, fun); + + for (i = 0; i < num / ITEMSIZE; i++) + { + int l/*ine*/, r/*everse*/; + int linebuf[ITEMS_PER_LINE]; + + if (0 == (i % ITEMS_PER_LINE)) // + printf("%04zX: ", i * ITEMSIZE); // print the address + linebuf[i % ITEMS_PER_LINE] = getitem(bus, dev, fun, i * ITEMSIZE); // get the value to a temporary line buffer + printf(FMTSTR, (int)(ITEM_MASK & linebuf[i % ITEMS_PER_LINE])); // print the value in hex format + // + if (0 == ((i + 1) % (ITEMS_PER_LINE / 2)) // check mid of line + && 0 != ((i + 1) % ITEMS_PER_LINE)) // + printf("- "); // print the separator + // + if (0 == ((i + 1) % ITEMS_PER_LINE)) // check end of line + { // + printf(" "); // insert space after hex print, + for (l = 0; l < ITEMS_PER_LINE; l++) // print ASCII representation + { // + for (r = ITEMSIZE * 8 - 8; r >= 0; r -= sizeof(char) * 8) // + { // + int v = linebuf[l] >> r; // + printf("%c", isalnum(0xFF & v) ? 0xFF & v : '.'); // + } // + printf(ITEMSIZE > 1 ? " " : ""); // + } // + printf("\n"); // new line + } + } +} + +int main(int argc, char** argv) +{ + int t, bus, dev, fun, headertype, vendev; + + if (argc < 4 && 0 != strcmp("/all", argv[1])) { + printf("ERROR: PCIdmp32 missing parameter, use:\n PCIdmp32 bus dev fun -- hex format\n PCIdmp32 /all\n"); + exit(EXIT_FAILURE); + } + + if (0 == strcmp(argv[1], "/all")) { + for (bus = 0; bus < 256; bus++) // scan all busses ... + for (dev = 0; dev < 32; dev++) // ...all devices on each bus.. + for (fun = 0; fun < 8; fun++) { // ...and all functions on each device + vendev = getitem(bus, dev, fun, 0); // get vendor/device ID from offest 0 + if (-1 == vendev) // continue when no device found (0xFFFFFFFF) + continue; // + // + dumpdev(bus, dev, fun); // dump the entire PCI header + // + headertype = getitem(bus, dev, fun, 0xC); // check header type ... + headertype >>= 16; // + if (fun == 0 && !(headertype & 0x80/*multi fun bit*/)) // ... if function 0 to be a multifuction device + break;//for(fun = 0 ; fun < 8 ; fun ++) // ... continue with next device if not + } + } + else { + t = sscanf(argv[1], "%x", &bus); + t = sscanf(argv[2], "%x", &dev); + t = sscanf(argv[3], "%x", &fun); + // additionally the numbers of tokens scanned can be checked, ignored here + + dumpdev(bus, dev, fun); // dump the entire PCI header + } + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/blogs/2021-11-14/pciwr.c b/blogs/2021-11-14/pciwr.c new file mode 100644 index 00000000000..263530be841 --- /dev/null +++ b/blogs/2021-11-14/pciwr.c @@ -0,0 +1,35 @@ +// +// PCI write tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include + +int setitem(int bus, int dev, int fun, int reg, int data) +{ + outpd(0xCF8, 0x80000000 + (bus << 16) + (dev << 11) + (fun << 8) + 0xFF & (reg & ~3)); + outp(0xCFC + (3 & reg), data); + return 0; +} + +int main(int argc, char** argv) +{ + int t, bus, dev, fun, reg, val; + + if (argc < 6) { + printf("ERROR: PCIwr missing parameter, use:\n PCIwr bus dev fun reg val -- hex format\n"); + exit(1); + } + + t = sscanf(argv[1], "%x", &bus); + t = sscanf(argv[2], "%x", &dev); + t = sscanf(argv[3], "%x", &fun); + t = sscanf(argv[4], "%x", ®); + t = sscanf(argv[5], "%x", &val); + // additionally the numbers of tokens scanned can be checked, ignored here + + setitem(bus, dev, fun, reg, val); + +} \ No newline at end of file diff --git a/blogs/2021-11-14/pciwr16.c b/blogs/2021-11-14/pciwr16.c new file mode 100644 index 00000000000..fa262753011 --- /dev/null +++ b/blogs/2021-11-14/pciwr16.c @@ -0,0 +1,35 @@ +// +// PCI write 16 tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include + +int setitem(int bus, int dev, int fun, int reg, int data) +{ + outpd(0xCF8, 0x80000000 + (bus << 16) + (dev << 11) + (fun << 8) + 0xFF & (reg & ~3)); + outpw(0xCFC + (3 & reg), data); + return 0; +} + +int main(int argc, char** argv) +{ + int t, bus, dev, fun, reg, val; + + if (argc < 6) { + printf("ERROR: PCIwr16 missing parameter, use:\n PCIwr16 bus dev fun reg val -- hex format\n"); + exit(1); + } + + t = sscanf(argv[1], "%x", &bus); + t = sscanf(argv[2], "%x", &dev); + t = sscanf(argv[3], "%x", &fun); + t = sscanf(argv[4], "%x", ®); + t = sscanf(argv[5], "%x", &val); + // additionally the numbers of tokens scanned can be checked, ignored here + + setitem(bus, dev, fun, reg, val); + +} \ No newline at end of file diff --git a/blogs/2021-11-14/pciwr32.c b/blogs/2021-11-14/pciwr32.c new file mode 100644 index 00000000000..efcead7a056 --- /dev/null +++ b/blogs/2021-11-14/pciwr32.c @@ -0,0 +1,35 @@ +// +// PCI write 32 tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include + +int setitem(int bus, int dev, int fun, int reg, int data) +{ + outpd(0xCF8, 0x80000000 + (bus << 16) + (dev << 11) + (fun << 8) + 0xFF & (reg & ~3)); + outpd(0xCFC + (0 & reg), data); + return 0; +} + +int main(int argc, char** argv) +{ + int t, bus, dev, fun, reg, val; + + if (argc < 6) { + printf("ERROR: PCIwr32 missing parameter, use:\n PCIwr32 bus dev fun reg val -- hex format\n"); + exit(1); + } + + t = sscanf(argv[1], "%x", &bus); + t = sscanf(argv[2], "%x", &dev); + t = sscanf(argv[3], "%x", &fun); + t = sscanf(argv[4], "%x", ®); + t = sscanf(argv[5], "%x", &val); + // additionally the numbers of tokens scanned can be checked, ignored here + + setitem(bus, dev, fun, reg, val); + +} \ No newline at end of file diff --git a/blogs/2021-11-14/repoclone.png b/blogs/2021-11-14/repoclone.png new file mode 100644 index 00000000000..e1c03d005a3 Binary files /dev/null and b/blogs/2021-11-14/repoclone.png differ diff --git a/blogs/2021-11-14/rtcdmp.c b/blogs/2021-11-14/rtcdmp.c new file mode 100644 index 00000000000..10c34bf2f1e --- /dev/null +++ b/blogs/2021-11-14/rtcdmp.c @@ -0,0 +1,45 @@ +// +// RTC dump tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include +#include + +unsigned char getitem(int index) +{ + //NOTE: "update in progress" is ignored + outp(0x70, index); // write the index + return (unsigned char)inp(0x71); // get the data +} + +int main() +{ + int i; + + for (i = 0; i < 128; i++) + { + int l; + unsigned char linebuf[16]; + + if (0 == (i % 16)) // + printf("%02X: ", i); // print the address + linebuf[i % 16] = getitem(i); // get the value to a temporary line buffer + printf("%02X ", linebuf[i % 16]); // print the value in hex format + // + if (0 == ((i + 1) % 8) // check mid of line + && 0 != ((i + 1) % 16)) // + printf("- "); // print the separator + // + if (0 == ((i + 1) % 16)) // check end of line + { // + printf(" "); // insert space after hex print, + for (l = 0; l < 16; l++) // print ASCII representation + printf("%c", isalnum(linebuf[l]) ? 0xFF & linebuf[l] : '.'); + printf("\n"); // new line + } + } + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/blogs/2021-11-14/rtcdmp.png b/blogs/2021-11-14/rtcdmp.png new file mode 100644 index 00000000000..2861ea6e2e7 Binary files /dev/null and b/blogs/2021-11-14/rtcdmp.png differ diff --git a/blogs/2021-11-14/rtcwr.c b/blogs/2021-11-14/rtcwr.c new file mode 100644 index 00000000000..80080c95d41 --- /dev/null +++ b/blogs/2021-11-14/rtcwr.c @@ -0,0 +1,32 @@ +// +// RTC write tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// +#include +#include + +int setitem(int index, int data) +{ + outp(0x70, index); + outp(0x71, data); + return 0; +} + +int main(int argc, char** argv) +{ + int index, data, t; + + if (argc < 3) { + printf("ERROR: RTCwr missing parameter, use:\n RTCwr index value -- hex format\n"); + exit(1); + } + + t = sscanf(argv[1], "%x", &index); + t = sscanf(argv[2], "%x", &data); + // additionally the numbers of tokens scanned can be checked, ignored here + + setitem(index, data); + +} \ No newline at end of file diff --git a/blogs/2021-11-14/siodmp.c b/blogs/2021-11-14/siodmp.c new file mode 100644 index 00000000000..ef4d8565856 --- /dev/null +++ b/blogs/2021-11-14/siodmp.c @@ -0,0 +1,132 @@ +// +// SIO dump tool +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// + +#include +#include +#include +#include + +#define FMTSTR "%02X "/*char*/ +#define TYPE char +#define ITEMSIZE sizeof(TYPE) +#define ITEMS_PER_LINE (16 / ITEMSIZE) +#define ITEM_MASK ((1LL << (8 * ITEMSIZE))-1) + +void help(int argc, char** argv); // prototype for help() + +#define IODELAY if(1){int xx = 8;while(xx--)outp(0xED,0x55);} + +unsigned getitem(int key, int cfgbase, int dev, int reg) { +#define IDX cfgbase +#define DAT (cfgbase+1) + unsigned bRet; + + outp(IDX, key); IODELAY; + outp(IDX, key); IODELAY; + outp(IDX, 0x7); IODELAY; + outp(DAT, dev); IODELAY; + outp(IDX, reg); IODELAY; + + bRet = inp(DAT); IODELAY; + + outp(IDX, 0xAA); IODELAY; + //printf("Base: %02X Key: %02X reg: %02X -> %02X\n", cfgbase, key, reg, bRet); + return bRet; +} + +int main(int argc, char** argv) { + int dev = 0, devend = 0x16, cfgbase = 0, key; + unsigned ID_H, ID_L; + int nRet = 0; + int i, num = 256; + + help(argc, argv); // check command line parameter + + do + { + for (key = 0x55; key <= 0x87; key += 0x32 /* NOTE: 0x55 + 0x32 == 0x87 */) { + for (cfgbase = 0x2E; cfgbase <= 0x4E; cfgbase += 0x20) { + + ID_H = getitem(key, cfgbase, 0, 0x20); + ID_L = getitem(key, cfgbase, 0, 0x21); + + if ((0xFF & ID_H) != 0xFF || (0xFF & ID_L) != 0xFF) + break; + } + if ((0xFF & ID_H) != 0xFF || (0xFF & ID_L) != 0xFF) + break; + } + + if (cfgbase > 0x4e) { + nRet = 1; + puts("SuperI/O not found\n"); + break; + } + + if (argc < 2) { // print help screen + printf(" %s \n %s /info\n %s /all\n\n", argv[0], argv[0], argv[0]); + break; + } + + if (0 == strcmp(argv[1], "/info")) { + printf("SuperI/O index/data base is 0x%02X, ID is %02X%02X\n", cfgbase, 0xFF & ID_H, 0xFF & ID_L); + break; + } + + if (0 != strcmp(argv[1], "/all")) { + sscanf(argv[1], "%x", &dev); + devend = dev + 1; + } + + do { + printf("device 0x%X\n", 0xFF & dev); + for (i = 0; i < num / ITEMSIZE; i++) + { + int l/*ine*/, r/*everse*/; + int linebuf[ITEMS_PER_LINE]; + + if (0 == (i % ITEMS_PER_LINE)) // + printf("%04zX: ", i * ITEMSIZE); // print the address + linebuf[i % ITEMS_PER_LINE] = getitem(key, cfgbase, dev, i * ITEMSIZE);// get the value to a temporary line buffer + printf(FMTSTR, (int)(ITEM_MASK & linebuf[i % ITEMS_PER_LINE])); // print the value in hex format + // + if (0 == ((i + 1) % (ITEMS_PER_LINE / 2)) // check mid of line + && 0 != ((i + 1) % ITEMS_PER_LINE)) // + printf("- "); // print the separator + // + if (0 == ((i + 1) % ITEMS_PER_LINE)) // check end of line + { // + printf(" "); // insert space after hex print, + for (l = 0; l < ITEMS_PER_LINE; l++) // print ASCII representation + { // + for (r = ITEMSIZE * 8 - 8; r >= 0; r -= sizeof(char) * 8) // + { // + int v = linebuf[l] >> r; // + printf("%c", isalnum(0xFF & v) ? 0xFF & v : '.'); // + } // + printf(ITEMSIZE > 1 ? " " : ""); // + } // + printf("\n"); // new line + } + } + } while (++dev < devend); + + } while (0); + + return(nRet); +} + +void help(int argc, char** argv) +{ + // ----- check argument count and help request, kept very simple + + if (argc < 2 || (argc > 1 && !strcmp(argv[1], "/?"))) + { + printf("siodmp [/all] [/info] dev\n"); + exit(1); + } +} \ No newline at end of file diff --git a/blogs/2021-11-14/welcomelist.png b/blogs/2021-11-14/welcomelist.png new file mode 100644 index 00000000000..ba55636d366 Binary files /dev/null and b/blogs/2021-11-14/welcomelist.png differ diff --git a/blogs/2021-11-28/.gitignore b/blogs/2021-11-28/.gitignore new file mode 100644 index 00000000000..1bc26e725c5 --- /dev/null +++ b/blogs/2021-11-28/.gitignore @@ -0,0 +1,3 @@ +*.efi +*.obj +a.out diff --git a/blogs/2021-11-28/ASCIIutf16.png b/blogs/2021-11-28/ASCIIutf16.png new file mode 100644 index 00000000000..b312cdec8b6 Binary files /dev/null and b/blogs/2021-11-28/ASCIIutf16.png differ diff --git a/blogs/2021-11-28/FixDiff.png b/blogs/2021-11-28/FixDiff.png new file mode 100644 index 00000000000..1ed31c5c820 Binary files /dev/null and b/blogs/2021-11-28/FixDiff.png differ diff --git a/blogs/2021-11-28/MdePkgInc b/blogs/2021-11-28/MdePkgInc new file mode 160000 index 00000000000..11a4229fee3 --- /dev/null +++ b/blogs/2021-11-28/MdePkgInc @@ -0,0 +1 @@ +Subproject commit 11a4229fee3b0791686de6cff7cb02050d3b85f0 diff --git a/blogs/2021-11-28/README.md b/blogs/2021-11-28/README.md new file mode 100644 index 00000000000..47362f9ace8 --- /dev/null +++ b/blogs/2021-11-28/README.md @@ -0,0 +1,566 @@ +### CdePkgBlog 2021-11-28 +# Using UEFI- and Standard-C-API in shell applications, creating MSDOS Tools for UEFI +![visualMSDOSUefiWide.png](https://github.com/KilianKegel/Visual-DOS-Tools-for-UEFI-Shell/blob/master/visualMSDOSUefiWide.png) +### Table of content +* [Abstract](README.md#Abstract) +* [Introduction](README.md#Introduction) + * [introductory email](https://edk2.groups.io/g/devel/topic/cdepkgblog_2021_11_18/87363412?p=,,,20,0,0,0::recentpostdate/sticky,,,20,2,0,87363412,previd=1638131716272402469,nextid=1637941879803363607&previd=1638131716272402469&nextid=1637941879803363607) +* [Latest available release](https://github.com/KilianKegel/Visual-DOS-Tools-for-UEFI-Shell) +* [In a nutshell: `FIND.EFI`](README.md#in-a-nutshell-findefi) +* [Building: `FIND.EFI`](README.md#building-findefi) +* [Internal Processing: FIND.C](README.md#internal-processing-findc) + * [Limitation parameter order](README.md#limitation-parameter-order) + * [Finding file(s) to be processed](README.md#finding-files-to-be-processed) + * [Dealing with ASCII and UCS2/UTF16LE file format](README.md#dealing-with-ascii-and-ucs2utf16le-file-format) + * [Reading lines from `stdin`](README.md#reading-lines-from-stdin) + * [1. stdin is directly connected to the console](README.md#1-stdin-is-directly-connected-to-the-console) + * [2. stdin is redirected, BOM is not detected](README.md#2-stdin-is-redirected-bom-is-not-yet-detected) + * [3. stdin is redirected, BOM is detected](README.md#3-stdin-is-redirected-bom-is-detected) + * [Reading lines from file(s)](README.md#reading-lines-from-files) + * [Exitcodes](README.md#exitcodes-findefi) +* [In a nutshell: `MORE.EFI`](README.md#in-a-nutshell-morefi) +* [Building: `MORE.EFI`](README.md#building-moreefi) +* [Internal Processing: MORE.C](README.md#internal-processing-morec) +* [Retrospective CdePkgBlog 2021-11-14](README.md#retrospective-cdepkgblog-2021-11-14) +* [Coming up soon](README.md#coming-up-soon) + +## Abstract +Demonstration on how to re-create and port software tools +that run in UEFI Shell, Microsoft Windows and Linux too and take benefit of the portability +given by the standardization of the C language, using the latest development environment from Microsoft and the *open source*, *monolithic*, *multi-target* +[**toro C Library**](https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library) + +NOTE: All statements regarding implementation specific details of **toro C Library** are always strictly focused on +my observations of Microsoft C Library, running "C" locale, at UTC timezone. Refering to Standard/ANSI C might be a +Microsoft specific implementation of the specification. But I always give my best to double check the statements on GCC x64. In critical cases +also old Borland, Watcom and Digital Mars C compiler and library were queried. **toro C Library** is engineered -- not "scientifized". +This is also true for all upcoming CdePkgBlogs. + +## Introduction + +In this blog I'd like to introduce software tools written in pure [Standard/ANSI C](http://www.torek.net/torek/c/index.html), +without any direct interaction with the operating system or direct hardware access. + +I chose a simple command line tool `FIND.EXE`. As far as I know `FIND.EXE` is an original MSDOS external command, +since it does not belong to CP/M. `find` in UNIX/Linux has a different approach. For UNIX/Linux `grep` +seems to be most similar to `FIND.EXE`, but more powerful. + +Afterwards the `more` command will be discussed. Its missing has been permanently irritating me during the past decade when using UEFI Shell, +since the PAGEUP scroll back capabilities are limited, and UEFI Shell command `DMPSTORE` only works sufficently +combined with `more`. `more` (truly **toro C Clibary** specific implementation) significantly improves CTRL-C break, +that is processed only on variable boundries in `DMPSTORE`. + +This blog shall encourage engineers to start porting tools from MSDOS +to the UEFI Shell, like `fdisk`, `format`, `sort`, `debug`, `choice`, `fc`, `tree` +and a real `mode` . + + `grep` and some other UNIX/Linux tools were already ported a couple of years ago by Andrei Warkentin:
+https://github.com/andreiw/UefiToolsPkg/tree/master/Applications/grep + +# In a nutshell: `FIND.EFI` + +`FIND.EFI` is a simple tool that searches `search string` line wise in a file.
+The file can be either one or more file(s) or `stdin`. Both are accepted in ASCII- and in UTF16LE mode.
+The operation can be parametrized to search:
+* case insensitive +* precede the line number to match +* inverted search - exclude lines that doesn't contain `search string` +* count matches only +``` + Searches for a text string in a file or files or in STDIN + + FIND "string" [/V][/C][/N][/I] [[drive:][path]filename[...]] + + "string" Specifies the text string to find. It must be the first parameter + /V or /v Displays all lines NOT containing the specified string. + /C or /c Displays only the count of lines containing the string. + /N or /n Displays line numbers with the displayed lines. + /I or /i Ignores the case of characters when searching for the string. + [drive:][path] filename + Specifies a file or files to search. + + If a path is not specified, FIND searches the text typed at the prompt + or piped from another command. +``` + +This `FIND` implementation uses the first parameter (`argv[1]`) *always* as the `"search string"`, +except in case `argv[1]` is `/?`. +The cause is explained below. Afterwards `FIND` tries to find the switches, always beginning with a slash `/`-charcter. +All other parameters are filenames, to be processed. + +If not at least one single filename is given, `FIND` uses `stdin` instead. That could be a redirected file output using the shell's pipe operator `|` or `|a` +or a direct console input. + +## Building: `FIND.EFI` +`FIND.EFI` is created in the VS2022CLI box.
+To start this, please refer to https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2021-11-14#starting-visual-studio-2022
+ +It is created out of one single file of sourcecode: [`FIND.C`](find.c). + +If you want to build `FIND.EFI` only, and not its Windows-versions, just type:
+`cl /nologo /GS- /D_NO_CRT_STDIO_INLINE /D_CRT_SECURE_NO_WARNINGS find.c /link /NODEFAULTLIB /ENTRY:_cdeCRT0UefiShell /SUBSYSTEM:EFI_APPLICATION /out:find.efi lib\toroC64.lib` + +Otherwise
+1. you want to create the **toro C Library** Windows version, link:
+ `link /nologo /NODEFAULTLIB /ENTRY:_cdeCRT0WinNT /SUBSYSTEM:console /out:find.exe find.obj lib\toroC64.lib kernel32.lib`
+2. you want to create the **Microsoft LIBCMT.lib** Windows version, link:
+ `link /nologo /SUBSYSTEM:console /out:findMsft.exe find.obj`
+3. you want to create a Linux/ELF64 version, just invoke the Linux C compiler in [UEFI-Development-PC with WSL](https://github.com/KilianKegel/HowTo-setup-an-UEFI-Development-PC#16-install-windows-subsystem-for-linux-wsl2--ubuntu-2004)
+ `wsl cc find.c` + +## Internal processing: FIND.C +### Limitation parameter order +Using Standard/ANSI C only there appears to be a problem in transferring the `"search string"` to the `main()`-function. + +Since in its original Microsoft Windows-version `"search string"` can be placed in any order with the other parameters, +it has to be the first one in this *portable Standard/ANSI C implemenation*.
+ +The reason is very simple:
+The enclosing quotation marks prevent the scanner from splitting at space characters. Parts of the commandline inside `""` +gets one single `argv[]`; inside `main()` the `""` quotation marks are not visible.
+https://docs.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments
+ +In **toro C Library** that corresponding function is called [`_cdeStr2Argcv()`](_cdeStr2Argcv.c). + +Since this piece of source code runs when linking **toro C Library** for Windows and for UEFI Shell, +its correctness was proven in the Windows command line and compared to a original Microsoft LIBCMT.LIB build with many different test patterns. + +### Finding file(s) to be processed +The files to be processed are checked [here](find.c#L124) +```c +[122] do { +[123] // +[124] // check, if filename is passed in the commandline. If not, read from file instead from STDIN +[125] // +[126] if (0 < cntFile ) { // take filename from commandline +[127] if (!IsFile(argv, iargv)) +[128] continue; +[129] if (NULL == (fp = fopen(argv[iargv], "r"))) { +[130] fprintf(stderr, "File not found - %s\n", argv[iargv]); // file is not present... +[131] exit(1); +[132] } +``` +In case real filename(s) are passed in the command line each filename +is used to [open the file](find.c#L129). + +If not so, [``` FILE* fp = stdin```](find.c#L44) is initialized at definition +and `stdin` will be used instead. + +### Dealing with ASCII and UCS2/UTF16LE file format + +UEFI specifies ASCII and UCS2 format for characters. + +![ASCIIutf16](ASCIIutf16.png) +![ucs2utf16](ucs2utf16.png) + +In Files ASCII vs. UCS2 differentiation is done by a [**byte order mark/BOM**](https://en.wikipedia.org/wiki/Byte_order_mark) +with a value of 0xFEFF. + +```c +[145] +[146] if (2 <= fsize) +[147] { +[148] unsigned short BOM; +[149] +[150] fread(&BOM, 2, 1, fp); +[151] +[152] fUTF16 = (0xFEFF == BOM); +[153] +[154] if(0 == fUTF16) +[155] rewind(fp); +[156] +[157] } +[158] +``` + +In case the `BOM` is not found, the file index needs to be set to 0 to get the first two ASCII characters +from the text file. + +### Reading lines from `stdin` +When getting the lines from `stdin` this differentiation is not needed, +since in the **toro C Library** implementation `stdin` internally always provides ASCII-format only. +##### NOTE: Wide functions based on `fgetwc()` just stretch single byte characters to wide size. Getting true UTF16LE access to files needs additional, non-standard `fopen()` flags, that are not yet available in **toro C Library**: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen?view=msvc-170#unicode-support + +There are three different cases, handled internally/automatically by the *operating system interface (`osif`)* +[`osifUefiShellFileRead()`](osifUefiShellFileRead.c) + +![operating system interface](https://github.com/tianocore/edk2-staging/blob/CdePkg/archview.png) + +#### 1. `stdin` is directly connected to the console +```c + +[52] #define OPENMODE pCdeFile->openmode + +[55] +[56] if (OPENMODE & O_CDESTDIN) +[57] { +[58] static wchar_t wcbuffer[BUFSIZ];/* BUFSIZ can not be changed on STDIN */ +[59] +[60] if (0 == (OPENMODE & O_CDEREDIR)) +[61] {// keyboard is connected directly, BOM is NOT transmitted, terminated by users's ENTER, but this ENTER is not transmitted +[62] +[63] BufferSize = (nelem - 2/*reserve space for CRLF */) * 2; +[64] +[65] Status = __cdeOnErrSet_status(pCdeFile->pRootProtocol->Read(pCdeFile->pFileProtocol, &BufferSize, &wcbuffer[0])); +[66] +[67] if (EFI_SUCCESS != Status) +[68] break; +[69] +[70] for (i = 0; i < BufferSize / 2; i++) +[71] pBuffer[i] = (char)wcbuffer[i]; +[72] +[73] pBuffer[i + 0] = '\r'; +[74] pBuffer[i + 1] = '\n'; +[75] +[76] BufferSize = BufferSize / 2 + 2/* CRLF */; +[77] } +[78] + ``` + `if (0 == (OPENMODE & O_CDEREDIR))` (line 60 in the listing above) checks if `stdin` is redirected (that was detected while running through `CRT0()` ) + +`EFI_FILE_PROTOCOL.Read()` returns the keys pressed on the keyboard until ENTER as a string of wide characters, placed in `wcbuffer[]`.
+ENTER itself is *not* transmitted. + +After converting the wide character string to an ASCII string (line 70 in the listing above), CR and LF were appended (line 73, 74 in the listing above) to the string +and afterwards hand over back to `fread()`. + +#### 2. `stdin` is redirected, BOM is not yet detected +```c + +[52] #define OPENMODE pCdeFile->openmode + +[80] +[81] if (0 == (OPENMODE & O_CDEDETECTED)) +[82] { +[83] size_t BufferSizeBOM = 2; +[84] // +[85] // read first TWO bytes and detect if it is BOM == 0xFEFF, if yes 16bit input, otherwise ASCII +[86] // +[87] wcbuffer[0] = 0; +[88] Status = __cdeOnErrSet_status(pCdeFile->pRootProtocol->Read(pCdeFile->pFileProtocol, &BufferSizeBOM, pwcBuffer/* == pBuffer */)); +[89] if (EFI_SUCCESS != Status) +[90] break; +[91] +[92] if (pwcBuffer[0] == BOM)/* == pBuffer[0..1] */ +[93] { +[94] OPENMODE |= O_CDEDETECTED + O_CDEWIDTH16; +[95] +[96] BufferSize = nelem * 2; +[97] Status = __cdeOnErrSet_status(pCdeFile->pRootProtocol->Read(pCdeFile->pFileProtocol, &BufferSize, &wcbuffer[0])); +[98] +[99] if (EFI_SUCCESS != Status) +[100] break; +[101] +[102] for (i = 0; i < BufferSize / 2; i++) +[103] pBuffer[i] = (char)wcbuffer[i]; +[104] +[105] BufferSize = BufferSize / 2; +[106] } +[107] else { +[108] +[109] OPENMODE |= O_CDEDETECTED; +[110] +[111] BufferSize = nelem - 2/* two bytes already read */; +[112] Status = __cdeOnErrSet_status(pCdeFile->pRootProtocol->Read(pCdeFile->pFileProtocol, &BufferSize, &pBuffer[2/* two bytes already read */])); +[113] +[114] if (EFI_SUCCESS != Status) +[115] break; +[116] BufferSize += 2;/* two bytes already read */; +[117] } +[118] } +``` +When the application requests the *first* access to a `stdin` that is redirected from a file, and +its width is not yet detected `(0 == (OPENMODE & O_CDEDETECTED)`, the source above is applied. + +`EFI_FILE_PROTOCOL.Read()` gets the first two bytes and `O_CDEWIDTH16` is set to `OPENMODE` +depending on their value: +```c +[92] if (pwcBuffer[0] == BOM)/* == pBuffer[0..1] */ + +[94] OPENMODE |= O_CDEDETECTED + O_CDEWIDTH16; + +[109] OPENMODE |= O_CDEDETECTED; +``` + +After detection of width the internal buffer could be filled fully.
+**NOTE:** All file/stream accesses are *buffered* in C, even if `_IONBF` is set. In that case buffer size is +just reduced to hold `\r\n`.

+Independant of the number of bytes requested by `fread()`/`fwrite()` internally all +OS-reads/writes were done *buffer-size-wise*. This is fundamental for Standard C and simply called **"buffered I/O"** + +#### 3. `stdin` is redirected, BOM is detected +```c +[81] if (0 == (OPENMODE & O_CDEDETECTED)) +[82] { + +[118] } +[119] else { +[120] if (O_CDEWIDTH16 == (OPENMODE & O_CDEWIDTH16)) { +[121] BufferSize = nelem * 2; +[122] Status = __cdeOnErrSet_status(pCdeFile->pRootProtocol->Read(pCdeFile->pFileProtocol, &BufferSize, &wcbuffer[0])); +[123] +[124] if (EFI_SUCCESS != Status) +[125] break; +[126] +[127] for (i = 0; i < BufferSize / 2; i++) +[128] pBuffer[i] = (char)wcbuffer[i]; +[129] +[130] BufferSize = BufferSize / 2; +[131] +[132] } +[133] else { +[134] BufferSize = nelem; +[135] Status = __cdeOnErrSet_status(pCdeFile->pRootProtocol->Read(pCdeFile->pFileProtocol, &BufferSize, &pBuffer[0])); +[136] +[137] if (EFI_SUCCESS != Status) +[138] break; +[139] } +[140] +[141] } +``` +In case of `O_CDEWIDTH16` the `EFI_FILE_PROTOCOL.Read()` fills the `wcbuffer` with UTF16LE words that needs to +be shrunk to ASCII again (line 127, 128 in the listing above). + +Otherwise `EFI_FILE_PROTOCOL.Read()` transfers directly to the internal 'stdin' buffer space (line 135). + +### Reading lines from file(s) +Standard C provides the function [`fgets()`](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fgets-fgetws?view=msvc-170&viewFallbackFrom=vs-2019) +to read line-wise from a stream. A line is terminated by a new line character `'\n'`. +In **toro C Library** this function is implemented that way: [fgets.c](fgets.c) + +As already mentioned [above](README.md#note-wide-functions-based-on-fgetwc-just-stretch-single-byte-characters-to-wide-size-getting-true-utf16le-access-to-files-needs-additional-non-standard-fopen-flags-that-are-not-yet-available-in-toro-c-library-httpsdocsmicrosoftcomen-uscppc-runtime-libraryreferencefopen-wfopenviewmsvc-170unicode-support) +it makes no sense to use the wide version `fgetws()` here. + +Instead `fgets()` could be used to read until new line. +The wide (UTF16-LE) strings needs a small number of additional processing: +1. the buffer must be cleared to ZERO, since a wide string is terminated by a `(whar_t)'\0'`, but `fgets()` terminates with a [`(char)'\0'`](fgets.c#L67) only.
+ (lines 165, 220)
+2. The UTF16-LE characters have to be shrunk manually. (`while`-loop line 186-191)
+ **ATTENTION:** `wchar_t` is 16 bit wide on Microsoft platforms/compilers. On GNU/Linux it is 32 bit in size: http://www.firstobject.com/wchar_t-string-on-linux-osx-windows.htm
+ Therefore type `short`is used instead of `wchar_t`. `short`is the same size in Linux and Windows. + + +```c +[165] memset(pLineOrg, 0, MAXLINELEN); +[166] while (NULL != fgets(pLineOrg, MAXLINELEN, fp)) +[167] { +[168] int equality = (0 == parm[V]) || (0 == stringlen && 0 != parm[V]) ; +[169] int match; +[170] line++; +[171] +[172] // +[173] // convert wide character string (wcs) to string (str) +[174] // +[175] if (1 == fUTF16) { +[176] int x = 0; +[177] char c; +[178] +[179] //don't work for LINUX: +[180] // +[181] // wcstombs(pLineOrg, (wchar_t*)pLineOrg, MAXLINELEN); +[182] // +[183] // wchar_t size in Linux i 4, in Windows 2: +[184] // http://www.firstobject.com/wchar_t-string-on-linux-osx-windows.htm +[185] +[186] while ( +[187] c = pLineOrg[x * sizeof(short)], +[188] pLineOrg[x * sizeof(char)] = c, +[189] x++, +[190] c != '\0' +[191] ); +[192] fgetc(fp); // adjust file index to next UTF16-LE character, +[193] // get high-part of UTF16-LE from '\n' +[194] } + +[220] memset(pLineOrg, 0, (linelen + 1) * sizeof(wchar_t)); // clear old buffer before reading next line +[221] } +``` + +## Exitcodes: `FIND.EFI` +* 3: `Parameter format not correct` +* 3: `Invalid switch` +* 1: `File not found` +* 0: `Help` +* 1: find result negativ +* 0: find result positive + +# In a nutshell: `MORE.EFI` +`MORE.EFI` lists a text-file content page-wise on the screen. +the `more` command also exists on Windows and UNIX/Linux systems. +Surely it has its origin on the latter. + +Even like `FIND.EFI` it accepts file names given in the command line, otherwise `stdin` is in charge. + +This `MORE.EFI` is a minimal-implementation that doesn't have any other parameters. +It does not even check when `stdout` is redirected to a file and the key-press would not have been required. +It does also not check the length of a line, so if a wrap around occurs, one line on top of the screen is gone. + + +## Building: `MORE.EFI` +`MORE.EFI` is created in the VS2022CLI box.
+To start this, please refer to https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2021-11-14#starting-visual-studio-2022
+ +It is created out of one single file of sourcecode: [`MORE.C`](more.c). + +If you want to build `MORE.EFI` just type:
+`cl /nologo /GS- /D_NO_CRT_STDIO_INLINE /D_CRT_SECURE_NO_WARNINGS /IMdePkgInc /IMdePkgInc\X64 more.c /link /NODEFAULTLIB /ENTRY:_cdeCRT0UefiShell /OUT:more.efi /SUBSYSTEM:EFI_APPLICATION lib\toroC64.lib` + +## Internal processing: MORE.C +**toro C Library** is designed for primarily for UEFI.
+To enable that *really beautiful, really elegant* UEFI API accesses using the `SystemTable` +directly in the source code, **toro C Library**-based Standard C programs need `SystemTable` +and `ImageHandle` (`FileHandle` for PEI) passed on a sideway, that keeps the buildability of +the source code also for non-UEFI executables. Therefore there is no need for an additional non-Standard-C-Library function +(e.g. `_CdeGetSystemTable()`).
+I chose to extend the argument vector `argv[]` into the negative range: +* `argv[-1]`: `SystemTable` or `PeiServices ` +* `argv[-2]`: `ImageHandle` or `FileHandle` + +In the `more.c` source code below `SystemTable` and `ImageHandle`were retrieved in line 17 and 18 in the source listing below. + +To get number of lines `QueryMode()` is invoked in line 26, using a call into the `SystemTable`. + +From lines 36 to 50 the [file/`stdin`](README.md#finding-files-to-be-processed) and +[ASCII/UTF16](README.md#dealing-with-ascii-and-ucs2utf16le-file-format) detection is done in a similiar way as with `FIND.C` + +The entire stream is retrieved and simultaneously converted to ASCII representation during lines 56 and 67. +The buffer size is continuously increased byte by byte using the `realloc()` Standard C function. In case of an allocation error +the process is just `abort()`-ed. + +Once, the screen is fully filled with lines, `MORE` awaits a key to be pressed. Usually +a function called `kbhit()` is in charge. Regrettably `kbhit()` is not a member +of the Standard C Library and not available in **toro C Library**. +Lines 79 to 82 do the same on UEFI API basis. + +```c +[1] // +[2] // MSDOS/Windows/UNIX MORE command for UEFI Shell +[3] // +[4] // Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +[5] // SPDX - License - Identifier: BSD-2-Clause-Patent +[6] // +[7] +[8] #include +[9] #include +[10] #include +[11] #undef NULL +[12] #include +[13] +[14] #define ELC(x) ( sizeof(x) / sizeof(x[0]) ) // element count +[15] +[16] int main(int argc, char** argv) { +[17] EFI_SYSTEM_TABLE* pEfiSystemTable = (void*)(argv[-1]); // pEfiSystemTable is passed in argv[-1] +[18] EFI_HANDLE* hEfiImageHandle = (void*)(argv[-2]); // ImageHandle is passed in argv[-2] +[19] UINTN Cols, Rows, Line = 0; // +[20] int c, i, n = 1, idiv = 1; // +[21] char* pBuf, * p; // +[22] FILE* fp = stdin; // take file from STDIN, by default +[23] char fUTF16 = 0; // flag file format +[24] int nRet = EXIT_SUCCESS; +[25] +[26] pEfiSystemTable->ConOut->QueryMode( // get number of text lines of the screen +[27] pEfiSystemTable->ConOut, +[28] (UINTN)pEfiSystemTable->ConOut->Mode->Mode, +[29] &Cols, &Rows +[30] ); +[31] +[32] do { +[33] // +[34] // check, if filename is passed in the commandline. If so, read from file instead from STDIN +[35] // +[36] if (argc > 1) { // take filename from commandline +[37] if (NULL == (fp = fopen(argv[n], "r"))) { // open filename from commandline +[38] fprintf(stderr, "Cannot access file %s\n", argv[n]);// file is not present... +[39] nRet = EXIT_FAILURE; // set exit code +[40] break; // ...exit program +[41] } else { // detect file format +[42] // +[43] // check BOM byte order mark UTF-16 (LE) https://en.wikipedia.org/wiki/Byte_order_mark#UTF-16 +[44] // +[45] unsigned short BOM = 0; +[46] fread(&BOM, 2, 1, fp); +[47] fUTF16 = (0xFEFF == BOM); +[48] if (0 == fUTF16) +[49] rewind(fp); +[50] } +[51] } +[52] +[53] // +[54] // read from file/STDIN until EOF to continously enlarged buffer +[55] // +[56] idiv = fUTF16 ? 2 : 1; // adjust idiv to decide skip zero high byte +[57] pBuf = NULL; // inital request for realloc() +[58] for (i = 0 ; EOF != (c = fgetc(fp)); i++) { // read character from file/STDIN until EOF +[59] if(fUTF16) // if UTF16 file format... +[60] if (0 != (i % 2)) // ... if zero high byte... +[61] continue; // ... skip that byte and continue +[62] pBuf = realloc(pBuf, i / idiv + 1); // allocate buffer / increase buffersize +[63] if (NULL == pBuf) // check allocation failure... +[64] abort(); // ...abort(), if so +[65] pBuf[i / idiv] = (char)c; // store character in memory buffer +[66] } // +[67] pBuf[i / idiv] = '\0'; // set string termination +[68] +[69] // +[70] // Buffer contains the entire file now. Print file line-wise to the screen and stop after # rows and wait for key +[71] // +[72] for (Line = 0, p = strtok(pBuf, "\n"); p != NULL; Line++) // display the text screen wise +[73] { +[74] if (Rows == 1 + Line) { +[75] UINTN Index; +[76] EFI_INPUT_KEY Key; +[77] EFI_STATUS Status; +[78] printf("-- More --"); +[79] do { // read real kbhit(), since STDIN is redirected +[80] pEfiSystemTable->BootServices->WaitForEvent(1, pEfiSystemTable->ConIn->WaitForKey, &Index); +[81] Status = pEfiSystemTable->ConIn->ReadKeyStroke(pEfiSystemTable->ConIn, &Key); +[82] } while (EFI_SUCCESS != Status); +[83] printf("\n"); +[84] Line = 0; +[85] } +[86] printf("%s\n", p); // print the text line +[87] p = strtok(NULL, "\n"); // get the next text line +[88] } +[89] if(stdin != fp) +[90] fclose(fp); // close fp, that was opened above +[91] } while (++n < argc); // next file... +[92] +[93] return nRet; +[94] } +``` + +# Retrospective CdePkgBlog 2021-11-14 +The careful reader of my [first blog](https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2021-11-14#cdepkgblog-2021-11-14) was aware of the little differences in the output +of the `WELCOME, to ANSI C`, namely that in the Windows-Version there is one more empty line before +the shell (cmd.exe) places its prompt to the console.
+ +![HelloAnsiCUefi](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2021-11-14/Welcome2AnsiCToroCLibUefiShell.png) + +![HelloAnsiCWinNT](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2021-11-14/Welcome2AnsiCToroCLibWinNT.png) + +A special characteristic in the UEFI Shell is, that it places the command prompt to +the beginning of the last line written from the application, that gave back control to the shell. Please check +the output of "WELCOME, to ANSI C"-string that is not terminated by a new line `\n` character: +![Welcome2AnsiCwithoutCRUefiShell](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2021-11-14/Welcome2AnsiCwithoutCRUefiShell.png) + +Since this special characteristic is out for years and other applications rely on that (bug), it is called *feature* and +can not be fixed anymore. + +Because **toro C Library** and the **CdePkg** strive for maximum compatibility with Windows library and Windows shell behaviour, +that particular quirk could be workarounded by the fix below:
+In `CRT0` an additional CR+LF is written to `ConOut` after termination of `main()`, if `stdout`and `stderr` were not redirected to a file.
+ +![FixDiff](FixDiff.png) + + + +## Coming up soon... +1. 2021-11-28:
+ * Using UEFI- and Standard-C-API in shell applications
+ * Creating MSDOS tools.
+2. 2021-12-12:
+ * Adopting open source Visual-Studio projects to UEFI
+ * Introduction of the ACPCIA port to UEFI
+3. 2022-09-01:
+ * Introduction of how to calibrate a TSC-based software timer - on IBM-AT compatible UEFI platforms + diff --git a/blogs/2021-11-28/UTF16.log b/blogs/2021-11-28/UTF16.log new file mode 100644 index 00000000000..0c79816d838 Binary files /dev/null and b/blogs/2021-11-28/UTF16.log differ diff --git a/blogs/2021-11-28/UTF8.log b/blogs/2021-11-28/UTF8.log new file mode 100644 index 00000000000..1b0177dca1e --- /dev/null +++ b/blogs/2021-11-28/UTF8.log @@ -0,0 +1,1272 @@ +Variable RT+BS 'EFIGlobalVariable:BootCurrent' DataSize = 0x02 + 00000000: 01 00 *..* +Variable RT+BS 'EFIGlobalVariable:PlatformLangCodes' DataSize = 0x06 + 00000000: 65 6E 2D 55 53 00 *en-US.* +Variable RT+BS 'EFIGlobalVariable:ErrOutDev' DataSize = 0x1E + 00000000: 02 01 0C 00 D0 41 03 0A-00 00 00 00 01 01 06 00 *.....A..........* + 00000010: 00 02 02 03 08 00 00 14-01 80 7F FF 04 00 *..............* +Variable RT+BS 'EFIGlobalVariable:BootOptionSupport' DataSize = 0x04 + 00000000: 13 03 00 00 *....* +Variable RT+BS 'EFIGlobalVariable:ConInDev' DataSize = 0x44 + 00000000: 02 01 0C 00 D0 41 03 0A-00 00 00 00 01 01 06 00 *.....A..........* + 00000010: 00 1F 02 01 0C 00 D0 41-03 03 00 00 00 00 7F 01 *.......A........* + 00000020: 04 00 02 01 0C 00 D0 41-03 0A 00 00 00 00 01 01 *.......A........* + 00000030: 06 00 00 15 03 05 06 00-00 00 03 05 06 00 00 00 *................* + 00000040: 7F FF 04 00 *....* +Variable RT+BS 'EFIGlobalVariable:ConOutDev' DataSize = 0x1E + 00000000: 02 01 0C 00 D0 41 03 0A-00 00 00 00 01 01 06 00 *.....A..........* + 00000010: 00 02 02 03 08 00 00 14-01 80 7F FF 04 00 *..............* +Variable RT+BS 'EFIGlobalVariable:OsIndicationsSupported' DataSize = 0x08 + 00000000: 03 00 00 00 00 00 00 00- *........* +Variable RT+BS 'EFIGlobalVariable:PKDefault' DataSize = 0x36D + 00000000: A1 59 C0 A5 E4 94 A7 4A-87 B5 AB 15 5C 2B F0 72 *.Y.....J....\+.r* + 00000010: 6D 03 00 00 00 00 00 00-51 03 00 00 91 30 05 3B *m.......Q....0.;* + 00000020: 9F 6C CC 04 B1 AC E2 A5-1E 3B E5 F5 30 82 03 3D *.l.......;..0..=* + 00000030: 30 82 02 25 A0 03 02 01-02 02 10 CA CB DC 6C D4 *0..%..........l.* + 00000040: 53 C2 A2 49 47 46 4D 40-DC 6A DB 30 0D 06 09 2A *S..IGFM@.j.0...** + 00000050: 86 48 86 F7 0D 01 01 0B-05 00 30 2A 31 28 30 26 *.H........0*1(0&* + 00000060: 06 03 55 04 03 13 1F 41-53 55 53 54 65 4B 20 4E *..U....ASUSTeK N* + 00000070: 6F 74 65 62 6F 6F 6B 20-50 4B 20 43 65 72 74 69 *otebook PK Certi* + 00000080: 66 69 63 61 74 65 30 1E-17 0D 31 31 31 32 32 37 *ficate0...111227* + 00000090: 30 30 31 38 32 30 5A 17-0D 33 31 31 32 32 37 30 *001820Z..3112270* + 000000A0: 30 31 38 31 39 5A 30 2A-31 28 30 26 06 03 55 04 *01819Z0*1(0&..U.* + 000000B0: 03 13 1F 41 53 55 53 54-65 4B 20 4E 6F 74 65 62 *...ASUSTeK Noteb* + 000000C0: 6F 6F 6B 20 50 4B 20 43-65 72 74 69 66 69 63 61 *ook PK Certifica* + 000000D0: 74 65 30 82 01 22 30 0D-06 09 2A 86 48 86 F7 0D *te0.."0...*.H...* + 000000E0: 01 01 01 05 00 03 82 01-0F 00 30 82 01 0A 02 82 *..........0.....* + 000000F0: 01 01 00 83 F0 C9 66 5B-42 A1 F4 BE 4F 20 39 4A *......f[B...O 9J* + 00000100: 0C 99 21 61 64 64 03 14-2E 2B 28 08 8C BC D5 0B *..!add...+(.....* + 00000110: 4B 35 7A E4 90 CA 3C C7-F6 E9 E6 63 A8 F1 F9 FF *K5z...<....c....* + 00000120: 95 2C 86 92 ED 09 D8 30-D0 6B 7F 75 10 50 F1 E5 *.,.....0.k.u.P..* + 00000130: D2 17 EA DF 9F F5 F3 B8-D9 D9 84 C6 82 34 01 73 *.............4.s* + 00000140: AD A5 60 10 61 D9 20 33-F7 BC BA 1C 60 7D 64 FB *..`.a. 3....`}d.* + 00000150: CF 4C 2E 0E 0C B8 77 68-4A 53 73 C2 40 5C 89 C4 *.L....whJSs.@\..* + 00000160: 67 1B 46 E6 62 3C 3C DE-2F 85 76 56 24 03 E3 AB *g.F.b<<./.vV$...* + 00000170: 1F A1 21 6E 91 3B 30 AA-F2 CB FE 9E E4 E9 AF CC *..!n.;0.........* + 00000180: 29 BE BF F8 91 E8 58 64-6D FA 00 E6 02 C6 04 27 *).....Xdm......'* + 00000190: 6D F4 97 A7 BA FC 8B DC-F0 7C BB 60 5C B0 F7 0E *m........|.`\...* + 000001A0: 31 21 06 DD 80 B4 4B 2B-B2 AB 7A A4 F6 66 A1 CE *1!....K+..z..f..* + 000001B0: AB D8 87 82 4E F5 B0 98-14 E9 81 E7 09 6A 8A C6 *....N........j..* + 000001C0: 5C 2F D1 1D 14 2A F3 A7-59 09 89 B1 24 98 70 23 *\/...*..Y...$.p#* + 000001D0: C7 88 2B 05 E8 F7 DC 25-ED 15 72 1A 8E 4F 17 A5 *..+....%..r..O..* + 000001E0: 3A AE FF E1 BC 40 C2 EF-D1 C9 F0 4D 34 93 D2 32 *:....@.....M4..2* + 000001F0: F5 65 0F 02 03 01 00 01-A3 5F 30 5D 30 5B 06 03 *.e......._0]0[..* + 00000200: 55 1D 01 04 54 30 52 80-10 19 4E 3A 42 02 27 5A *U...T0R...N:B.'Z* + 00000210: 5A 6B A9 78 98 CA 7B D7-39 A1 2C 30 2A 31 28 30 *Zk.x..{.9.,0*1(0* + 00000220: 26 06 03 55 04 03 13 1F-41 53 55 53 54 65 4B 20 *&..U....ASUSTeK * + 00000230: 4E 6F 74 65 62 6F 6F 6B-20 50 4B 20 43 65 72 74 *Notebook PK Cert* + 00000240: 69 66 69 63 61 74 65 82-10 CA CB DC 6C D4 53 C2 *ificate.....l.S.* + 00000250: A2 49 47 46 4D 40 DC 6A-DB 30 0D 06 09 2A 86 48 *.IGFM@.j.0...*.H* + 00000260: 86 F7 0D 01 01 0B 05 00-03 82 01 01 00 43 E3 BB *.............C..* + 00000270: 15 68 CC 4E B3 45 DD 6A-F5 E5 67 5E 5B D4 4F C7 *.h.N.E.j..g^[.O.* + 00000280: 0D A2 83 E4 04 7C 0E 8A-85 78 BB 30 F1 4A 9A A0 *.....|...x.0.J..* + 00000290: BF 99 96 3F F5 8C 00 73-51 E6 BC 43 24 52 59 A3 *...?...sQ..C$RY.* + 000002A0: 56 ED 75 B5 05 5A EC 8B-63 25 F2 53 2D 9C 40 8A *V.u..Z..c%.S-.@.* + 000002B0: 24 C3 56 26 BC D2 B3 07-F9 C5 38 8A 61 67 CD 32 *$.V&......8.ag.2* + 000002C0: 3F 4C 9A 3F 2A 3C CB 33-0D 34 4E 67 7B DE B6 B7 *?L.?*<.3.4Ng{...* + 000002D0: BE D9 FA ED 53 5F 70 24-8E 3C 5A 71 C5 0D 65 11 *....S_p$.V\-'.&* + 000002C0: C7 DB 49 18 58 7A C8 AB-90 29 15 73 6A FD E4 4F *..I.Xz...).sj..O* + 000002D0: 0B EC AC A5 83 20 0F CE-B8 85 82 B4 B9 52 12 5C *..... .......R.\* + 000002E0: 6D A2 22 62 E7 4A EC AD-40 F3 B0 4E 19 A0 C7 9F *m."b.J..@..N....* + 000002F0: 13 37 9B 2D A1 58 A6 18-0E 24 B7 0B 79 8D E4 1F *.7.-.X...$..y...* + 00000300: 84 6F 19 97 52 C9 65 7A-0F 4E 14 F3 79 EE 2A 30 *.o..R.ez.N..y.*0* + 00000310: 7A 35 77 02 9D DB FA 9F-55 CF 13 AF 70 C3 8B 16 *z5w.....U...p...* + 00000320: B6 7A 11 E2 D3 86 DD E7-DD C4 E2 A9 F9 F5 96 8B *.z..............* + 00000330: BE 17 8C 42 7F 46 03 6B-B4 CC BD D4 A4 39 AC A7 *...B.F.k.....9..* + 00000340: DD 42 3E 95 3C 01 08 1D-D9 EE 7B 1C E3 FF 7C 56 *.B>.<.....{...|V* + 00000350: 50 7C 31 33 7E F3 EE C5-66 A6 17 E3 1D D6 9D D8 *P|13~...f.......* + 00000360: 18 5B 7B E2 ED 97 5D D7-C2 63 1D 49 CB BD 5F D7 *.[{...]..c.I.._.* + 00000370: A1 59 C0 A5 E4 94 A7 4A-87 B5 AB 15 5C 2B F0 72 *.Y.....J....\+.r* + 00000380: 18 06 00 00 00 00 00 00-FC 05 00 00 BD 9A FA 77 *...............w* + 00000390: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 30 82 05 E8 *Y.2M.`(...xK0...* + 000003A0: 30 82 03 D0 A0 03 02 01-02 02 0A 61 0A D1 88 00 *0..........a....* + 000003B0: 00 00 00 00 03 30 0D 06-09 2A 86 48 86 F7 0D 01 *.....0...*.H....* + 000003C0: 01 0B 05 00 30 81 91 31-0B 30 09 06 03 55 04 06 *....0..1.0...U..* + 000003D0: 13 02 55 53 31 13 30 11-06 03 55 04 08 13 0A 57 *..US1.0...U....W* + 000003E0: 61 73 68 69 6E 67 74 6F-6E 31 10 30 0E 06 03 55 *ashington1.0...U* + 000003F0: 04 07 13 07 52 65 64 6D-6F 6E 64 31 1E 30 1C 06 *....Redmond1.0..* + 00000400: 03 55 04 0A 13 15 4D 69-63 72 6F 73 6F 66 74 20 *.U....Microsoft * + 00000410: 43 6F 72 70 6F 72 61 74-69 6F 6E 31 3B 30 39 06 *Corporation1;09.* + 00000420: 03 55 04 03 13 32 4D 69-63 72 6F 73 6F 66 74 20 *.U...2Microsoft * + 00000430: 43 6F 72 70 6F 72 61 74-69 6F 6E 20 54 68 69 72 *Corporation Thir* + 00000440: 64 20 50 61 72 74 79 20-4D 61 72 6B 65 74 70 6C *d Party Marketpl* + 00000450: 61 63 65 20 52 6F 6F 74-30 1E 17 0D 31 31 30 36 *ace Root0...1106* + 00000460: 32 34 32 30 34 31 32 39-5A 17 0D 32 36 30 36 32 *24204129Z..26062* + 00000470: 34 32 30 35 31 32 39 5A-30 81 80 31 0B 30 09 06 *4205129Z0..1.0..* + 00000480: 03 55 04 06 13 02 55 53-31 13 30 11 06 03 55 04 *.U....US1.0...U.* + 00000490: 08 13 0A 57 61 73 68 69-6E 67 74 6F 6E 31 10 30 *...Washington1.0* + 000004A0: 0E 06 03 55 04 07 13 07-52 65 64 6D 6F 6E 64 31 *...U....Redmond1* + 000004B0: 1E 30 1C 06 03 55 04 0A-13 15 4D 69 63 72 6F 73 *.0...U....Micros* + 000004C0: 6F 66 74 20 43 6F 72 70-6F 72 61 74 69 6F 6E 31 *oft Corporation1* + 000004D0: 2A 30 28 06 03 55 04 03-13 21 4D 69 63 72 6F 73 **0(..U...!Micros* + 000004E0: 6F 66 74 20 43 6F 72 70-6F 72 61 74 69 6F 6E 20 *oft Corporation * + 000004F0: 4B 45 4B 20 43 41 20 32-30 31 31 30 82 01 22 30 *KEK CA 20110.."0* + 00000500: 0D 06 09 2A 86 48 86 F7-0D 01 01 01 05 00 03 82 *...*.H..........* + 00000510: 01 0F 00 30 82 01 0A 02-82 01 01 00 C4 E8 B5 8A *...0............* + 00000520: BF AD 57 26 B0 26 C3 EA-E7 FB 57 7A 44 02 5D 07 *..W&.&....WzD.].* + 00000530: 0D DA 4A E5 74 2A E6 B0-0F EC 6D EB EC 7F B9 E3 *..J.t*....m.....* + 00000540: 5A 63 32 7C 11 17 4F 0E-E3 0B A7 38 15 93 8E C6 *Zc2|..O....8....* + 00000550: F5 E0 84 B1 9A 9B 2C E7-F5 B7 91 D6 09 E1 E2 C0 *......,.........* + 00000560: 04 A8 AC 30 1C DF 48 F3-06 50 9A 64 A7 51 7F C8 *...0..H..P.d.Q..* + 00000570: 85 4F 8F 20 86 CE FE 2F-E1 9F FF 82 C0 ED E9 CD *.O. .../........* + 00000580: CE F4 53 6A 62 3A 0B 43-B9 E2 25 FD FE 05 F9 D4 *..Sjb:.C..%.....* + 00000590: C4 14 AB 11 E2 23 89 8D-70 B7 A4 1D 4D EC AE E5 *.....#..p...M...* + 000005A0: 9C FA 16 C2 D7 C1 CB D4-E8 C4 2F E5 99 EE 24 8B *........../...$.* + 000005B0: 03 EC 8D F2 8B EA C3 4A-FB 43 11 12 0B 7E B5 47 *.......J.C...~.G* + 000005C0: 92 6C DC E6 04 89 EB F5-33 04 EB 10 01 2A 71 E5 *.l......3....*q.* + 000005D0: F9 83 13 3C FF 25 09 2F-68 76 46 FF BA 4F BE DC *...<.%./hvF..O..* + 000005E0: AD 71 2A 58 AA FB 0E D2-79 3D E4 9B 65 3B CC 29 *.q*X....y=..e;.)* + 000005F0: 2A 9F FC 72 59 A2 EB AE-92 EF F6 35 13 80 C6 02 **..rY......5....* + 00000600: EC E4 5F CC 9D 76 CD EF-63 92 C1 AF 79 40 84 79 *.._..v..c...y@.y* + 00000610: 87 7F E3 52 A8 E8 9D 7B-07 69 8F 15 02 03 01 00 *...R...{.i......* + 00000620: 01 A3 82 01 4F 30 82 01-4B 30 10 06 09 2B 06 01 *....O0..K0...+..* + 00000630: 04 01 82 37 15 01 04 03-02 01 00 30 1D 06 03 55 *...7.......0...U* + 00000640: 1D 0E 04 16 04 14 62 FC-43 CD A0 3E A4 CB 67 12 *......b.C..>..g.* + 00000650: D2 5B D9 55 AC 7B CC B6-8A 5F 30 19 06 09 2B 06 *.[.U.{..._0...+.* + 00000660: 01 04 01 82 37 14 02 04-0C 1E 0A 00 53 00 75 00 *....7.......S.u.* + 00000670: 62 00 43 00 41 30 0B 06-03 55 1D 0F 04 04 03 02 *b.C.A0...U......* + 00000680: 01 86 30 0F 06 03 55 1D-13 01 01 FF 04 05 30 03 *..0...U.......0.* + 00000690: 01 01 FF 30 1F 06 03 55-1D 23 04 18 30 16 80 14 *...0...U.#..0...* + 000006A0: 45 66 52 43 E1 7E 58 11-BF D6 4E 9E 23 55 08 3B *EfRC.~X...N.#U.;* + 000006B0: 3A 22 6A A8 30 5C 06 03-55 1D 1F 04 55 30 53 30 *:"j.0\..U...U0S0* + 000006C0: 51 A0 4F A0 4D 86 4B 68-74 74 70 3A 2F 2F 63 72 *Q.O.M.Khttp://cr* + 000006D0: 6C 2E 6D 69 63 72 6F 73-6F 66 74 2E 63 6F 6D 2F *l.microsoft.com/* + 000006E0: 70 6B 69 2F 63 72 6C 2F-70 72 6F 64 75 63 74 73 *pki/crl/products* + 000006F0: 2F 4D 69 63 43 6F 72 54-68 69 50 61 72 4D 61 72 */MicCorThiParMar* + 00000700: 52 6F 6F 5F 32 30 31 30-2D 31 30 2D 30 35 2E 63 *Roo_2010-10-05.c* + 00000710: 72 6C 30 60 06 08 2B 06-01 05 05 07 01 01 04 54 *rl0`..+........T* + 00000720: 30 52 30 50 06 08 2B 06-01 05 05 07 30 02 86 44 *0R0P..+.....0..D* + 00000730: 68 74 74 70 3A 2F 2F 77-77 77 2E 6D 69 63 72 6F *http://www.micro* + 00000740: 73 6F 66 74 2E 63 6F 6D-2F 70 6B 69 2F 63 65 72 *soft.com/pki/cer* + 00000750: 74 73 2F 4D 69 63 43 6F-72 54 68 69 50 61 72 4D *ts/MicCorThiParM* + 00000760: 61 72 52 6F 6F 5F 32 30-31 30 2D 31 30 2D 30 35 *arRoo_2010-10-05* + 00000770: 2E 63 72 74 30 0D 06 09-2A 86 48 86 F7 0D 01 01 *.crt0...*.H.....* + 00000780: 0B 05 00 03 82 02 01 00-D4 84 88 F5 14 94 18 02 *................* + 00000790: CA 2A 3C FB 2A 92 1C 0C-D7 A0 D1 F1 E8 52 66 A8 *.*<.*........Rf.* + 000007A0: EE A2 B5 75 7A 90 00 AA-2D A4 76 5A EA 79 B7 B9 *...uz...-.vZ.y..* + 000007B0: 37 6A 51 7B 10 64 F6 E1-64 F2 02 67 BE F7 A8 1B *7jQ{.d..d..g....* + 000007C0: 78 BD BA CE 88 58 64 0C-D6 57 C8 19 A3 5F 05 D6 *x....Xd..W..._..* + 000007D0: DB C6 D0 69 CE 48 4B 32-B7 EB 5D D2 30 F5 C0 F5 *...i.HK2..].0...* + 000007E0: B8 BA 78 07 A3 2B FE 9B-DB 34 56 84 EC 82 CA AE *..x..+...4V.....* + 000007F0: 41 25 70 9C 6B E9 FE 90-0F D7 96 1F E5 E7 94 1F *A%p.k...........* + 00000800: B2 2A 0C 8D 4B FF 28 29-10 7B F7 D7 7C A5 D1 76 *.*..K.().{..|..v* + 00000810: B9 05 C8 79 ED 0F 90 92-9C C2 FE DF 6F 7E 6C 0F *...y........o~l.* + 00000820: 7B D4 C1 45 DD 34 51 96-39 0F E5 5E 56 D8 18 05 *{..E.4Q.9..^V...* + 00000830: 96 F4 07 A6 42 B3 A0 77-FD 08 19 F2 71 56 CC 9F *....B..w....qV..* + 00000840: 86 23 A4 87 CB A6 FD 58-7E D4 69 67 15 91 7E 81 *.#.....X~.ig..~.* + 00000850: F2 7F 13 E5 0D 8B 8A 3C-87 84 EB E3 CE BD 43 E5 *.......<......C.* + 00000860: AD 2D 84 93 8E 6A 2B 5A-7C 44 FA 52 AA 81 C8 2D *.-...j+Z|D.R...-* + 00000870: 1C BB E0 52 DF 00 11 F8-9A 3D C1 60 B0 E1 33 B5 *...R.....=.`..3.* + 00000880: A3 88 D1 65 19 0A 1A E7-AC 7C A4 C1 82 87 4E 38 *...e.....|....N8* + 00000890: B1 2F 0D C5 14 87 6F FD-8D 2E BC 39 B6 E7 E6 C3 *./....o....9....* + 000008A0: E0 E4 CD 27 84 EF 94 42-EF 29 8B 90 46 41 3B 81 *...'...B.)..FA;.* + 000008B0: 1B 67 D8 F9 43 59 65 CB-0D BC FD 00 92 4F F4 75 *.g..CYe......O.u* + 000008C0: 3B A7 A9 24 FC 50 41 40-79 E0 2D 4F 0A 6A 27 76 *;..$.PA@y.-O.j'v* + 000008D0: 6E 52 ED 96 69 7B AF 0F-F7 87 05 D0 45 C2 AD 53 *nR..i{......E..S* + 000008E0: 14 81 1F FB 30 04 AA 37-36 61 DA 4A 69 1B 34 D8 *....0..76a.Ji.4.* + 000008F0: 68 ED D6 02 CF 6C 94 0C-D3 CF 6C 22 79 AD B1 F0 *h....l....l"y...* + 00000900: BC 03 A2 46 60 A9 C4 07-C2 21 82 F1 FD F2 E8 79 *...F`....!.....y* + 00000910: 32 60 BF D8 AC A5 22 14-4B CA C1 D8 4B EB 7D 3F *2`....".K...K.}?* + 00000920: 57 35 B2 E6 4F 75 B4 B0-60 03 22 53 AE 91 79 1D *W5..Ou..`."S..y.* + 00000930: D6 9B 41 1F 15 86 54 70-B2 DE 0D 35 0F 7C B0 34 *..A...Tp...5.|.4* + 00000940: 72 BA 97 60 3B F0 79 EB-A2 B2 1C 5D A2 16 B8 87 *r..`;.y....]....* + 00000950: C5 E9 1B F6 B5 97 25 6F-38 9F E3 91 FA 8A 79 98 *......%o8.....y.* + 00000960: C3 69 0E B7 A3 1C 20 05-97 F8 CA 14 AE 00 D7 C4 *.i.... .........* + 00000970: F3 C0 14 10 75 6B 34 A0-1B B5 99 60 F3 5C B0 C5 *....uk4....`.\..* + 00000980: 57 4E 36 D2 32 84 BF 9E-A1 59 C0 A5 E4 94 A7 4A *WN6.2....Y.....J* + 00000990: 87 B5 AB 15 5C 2B F0 72-64 04 00 00 00 00 00 00 *....\+.rd.......* + 000009A0: 48 04 00 00 E4 0A C4 6D-E8 2E 4C 9C A3 14 0F C7 *H......m..L.....* + 000009B0: B2 00 87 10 30 82 04 34-30 82 03 1C A0 03 02 01 *....0..40.......* + 000009C0: 02 02 09 00 B9 41 24 A0-18 2C 92 67 30 0D 06 09 *.....A$..,.g0...* + 000009D0: 2A 86 48 86 F7 0D 01 01-0B 05 00 30 81 84 31 0B **.H........0..1.* + 000009E0: 30 09 06 03 55 04 06 13-02 47 42 31 14 30 12 06 *0...U....GB1.0..* + 000009F0: 03 55 04 08 0C 0B 49 73-6C 65 20 6F 66 20 4D 61 *.U....Isle of Ma* + 00000A00: 6E 31 10 30 0E 06 03 55-04 07 0C 07 44 6F 75 67 *n1.0...U....Doug* + 00000A10: 6C 61 73 31 17 30 15 06-03 55 04 0A 0C 0E 43 61 *las1.0...U....Ca* + 00000A20: 6E 6F 6E 69 63 61 6C 20-4C 74 64 2E 31 34 30 32 *nonical Ltd.1402* + 00000A30: 06 03 55 04 03 0C 2B 43-61 6E 6F 6E 69 63 61 6C *..U...+Canonical* + 00000A40: 20 4C 74 64 2E 20 4D 61-73 74 65 72 20 43 65 72 * Ltd. Master Cer* + 00000A50: 74 69 66 69 63 61 74 65-20 41 75 74 68 6F 72 69 *tificate Authori* + 00000A60: 74 79 30 1E 17 0D 31 32-30 34 31 32 31 31 31 32 *ty0...1204121112* + 00000A70: 35 31 5A 17 0D 34 32 30-34 31 31 31 31 31 32 35 *51Z..42041111125* + 00000A80: 31 5A 30 81 84 31 0B 30-09 06 03 55 04 06 13 02 *1Z0..1.0...U....* + 00000A90: 47 42 31 14 30 12 06 03-55 04 08 0C 0B 49 73 6C *GB1.0...U....Isl* + 00000AA0: 65 20 6F 66 20 4D 61 6E-31 10 30 0E 06 03 55 04 *e of Man1.0...U.* + 00000AB0: 07 0C 07 44 6F 75 67 6C-61 73 31 17 30 15 06 03 *...Douglas1.0...* + 00000AC0: 55 04 0A 0C 0E 43 61 6E-6F 6E 69 63 61 6C 20 4C *U....Canonical L* + 00000AD0: 74 64 2E 31 34 30 32 06-03 55 04 03 0C 2B 43 61 *td.1402..U...+Ca* + 00000AE0: 6E 6F 6E 69 63 61 6C 20-4C 74 64 2E 20 4D 61 73 *nonical Ltd. Mas* + 00000AF0: 74 65 72 20 43 65 72 74-69 66 69 63 61 74 65 20 *ter Certificate * + 00000B00: 41 75 74 68 6F 72 69 74-79 30 82 01 22 30 0D 06 *Authority0.."0..* + 00000B10: 09 2A 86 48 86 F7 0D 01-01 01 05 00 03 82 01 0F *.*.H............* + 00000B20: 00 30 82 01 0A 02 82 01-01 00 BF 5B 3A 16 74 EE *.0.........[:.t.* + 00000B30: 21 5D AE 61 ED 9D 56 AC-BD DE DE 72 F3 DD 7E 2D *!].a..V....r..~-* + 00000B40: 4C 62 0F AC C0 6D 48 08-11 CF 8D 8B FB 61 1F 27 *Lb...mH......a.'* + 00000B50: CC 11 6E D9 55 3D 39 54-EB 40 3B B1 BB E2 85 34 *..n.U=9T.@;....4* + 00000B60: 79 CA F7 7B BF BA 7A C8-10 2D 19 7D AD 59 CF A6 *y..{..z..-.}.Y..* + 00000B70: D4 E9 4E 0F DA AE 52 EA-4C 9E 90 CE C6 99 0D 4E *..N...R.L......N* + 00000B80: 67 65 78 5D F9 D1 D5 38-4A 4A 7A 8F 93 9C 7F 1A *gex]...8JJz.....* + 00000B90: A3 85 DB CE FA 8B F7 C2-A2 21 2D 9B 54 41 35 10 *.........!-.TA5.* + 00000BA0: 57 13 8D 6C BC 29 06 50-4A 7E EA 99 A9 68 A7 3B *W..l.).PJ~...h.;* + 00000BB0: C7 07 1B 32 9E A0 19 87-0E 79 BB 68 99 2D 7E 93 *...2.....y.h.-~.* + 00000BC0: 52 E5 F6 EB C9 9B F9 2B-ED B8 68 49 BC D9 95 50 *R......+..hI...P* + 00000BD0: 40 5B C5 B2 71 AA EB 5C-57 DE 71 F9 40 0A DD 5B *@[..q..\W.q.@..[* + 00000BE0: AC 1E 84 2D 50 1A 52 D6-E1 F3 6B 6E 90 64 4F 5B *...-P.R...kn.dO[* + 00000BF0: B4 EB 20 E4 61 10 DA 5A-F0 EA E4 42 D7 01 C4 FE *.. .a..Z...B....* + 00000C00: 21 1F D9 B9 C0 54 95 42-81 52 72 1F 49 64 7A C8 *!....T.B.Rr.Idz.* + 00000C10: 6C 24 F1 08 70 0B 4D A5-A0 32 D1 A0 1C 57 A8 4D *l$..p.M..2...W.M* + 00000C20: E3 AF A5 8E 05 05 3E 10-43 A1 02 03 01 00 01 A3 *......>.C.......* + 00000C30: 81 A6 30 81 A3 30 1D 06-03 55 1D 0E 04 16 04 14 *..0..0...U......* + 00000C40: AD 91 99 0B C2 2A B1 F5-17 04 8C 23 B6 65 5A 26 *.....*.....#.eZ&* + 00000C50: 8E 34 5A 63 30 1F 06 03-55 1D 23 04 18 30 16 80 *.4Zc0...U.#..0..* + 00000C60: 14 AD 91 99 0B C2 2A B1-F5 17 04 8C 23 B6 65 5A *......*.....#.eZ* + 00000C70: 26 8E 34 5A 63 30 0F 06-03 55 1D 13 01 01 FF 04 *&.4Zc0...U......* + 00000C80: 05 30 03 01 01 FF 30 0B-06 03 55 1D 0F 04 04 03 *.0....0...U.....* + 00000C90: 02 01 86 30 43 06 03 55-1D 1F 04 3C 30 3A 30 38 *...0C..U...<0:08* + 00000CA0: A0 36 A0 34 86 32 68 74-74 70 3A 2F 2F 77 77 77 *.6.4.2http://www* + 00000CB0: 2E 63 61 6E 6F 6E 69 63-61 6C 2E 63 6F 6D 2F 73 *.canonical.com/s* + 00000CC0: 65 63 75 72 65 2D 62 6F-6F 74 2D 6D 61 73 74 65 *ecure-boot-maste* + 00000CD0: 72 2D 63 61 2E 63 72 6C-30 0D 06 09 2A 86 48 86 *r-ca.crl0...*.H.* + 00000CE0: F7 0D 01 01 0B 05 00 03-82 01 01 00 3F 7D F6 76 *............?}.v* + 00000CF0: A5 B3 83 B4 2B 7A D0 6D-52 1A 03 83 C4 12 A7 50 *....+z.mR......P* + 00000D00: 9C 47 92 CC C0 94 77 82-D2 AE 57 B3 99 04 F5 32 *.G....w...W....2* + 00000D10: 3A C6 55 1D 07 DB 12 A9-56 FA D8 D4 76 20 EB E4 *:.U.....V...v ..* + 00000D20: C3 51 DB 9A 5C 9C 92 3F-18 73 DA 94 6A A1 99 38 *.Q..\..?.s..j..8* + 00000D30: 8C A4 88 6D C1 FC 39 71-D0 74 76 16 03 3E 56 23 *...m..9q.tv..>V#* + 00000D40: 35 D5 55 47 5B 1A 1D 41-C2 D3 12 4C DC FF AE 0A *5.UG[..A...L....* + 00000D50: 92 9C 62 0A 17 01 9C 73-E0 5E B1 FD BC D6 B5 19 *..b....s.^......* + 00000D60: 11 7A 7E CD 3E 03 7E 66-DB 5B A8 C9 39 48 51 FF *.z~.>.~f.[..9HQ.* + 00000D70: 53 E1 9C 31 53 91 1B 3B-10 75 03 17 BA E6 81 02 *S..1S..;.u......* + 00000D80: 80 94 70 4C 46 B7 94 B0-3D 15 CD 1F 8E 02 E0 68 *..pLF...=......h* + 00000D90: 02 8F FB F9 47 1D 7D A2-01 C6 07 51 C4 9A CC ED *....G.}....Q....* + 00000DA0: DD CF A3 5D ED 92 BB BE-D1 FD E6 EC 1F 33 51 73 *...].........3Qs* + 00000DB0: 04 BE 3C 72 B0 7D 08 F8-01 FF 98 7D CB 9C E0 69 *...........f..m* + 00000DE0: BD B8 27 77 C1 42 94 BD-FC 6A 0A BC *..'w.B...j..* +Variable RT+BS 'EFIGlobalVariable:dbDefault' DataSize = 0x17A6 + 00000000: A1 59 C0 A5 E4 94 A7 4A-87 B5 AB 15 5C 2B F0 72 *.Y.....J....\+.r* + 00000010: 79 03 00 00 00 00 00 00-5D 03 00 00 91 30 05 3B *y.......]....0.;* + 00000020: 9F 6C CC 04 B1 AC E2 A5-1E 3B E5 F5 30 82 03 49 *.l.......;..0..I* + 00000030: 30 82 02 31 A0 03 02 01-02 02 10 B8 E5 81 E4 DF *0..1............* + 00000040: 77 A5 BB 42 82 D5 CC FC-00 C0 71 30 0D 06 09 2A *w..B......q0...** + 00000050: 86 48 86 F7 0D 01 01 0B-05 00 30 2E 31 2C 30 2A *.H........0.1,0** + 00000060: 06 03 55 04 03 13 23 41-53 55 53 54 65 4B 20 4E *..U...#ASUSTeK N* + 00000070: 6F 74 65 62 6F 6F 6B 20-53 57 20 4B 65 79 20 43 *otebook SW Key C* + 00000080: 65 72 74 69 66 69 63 61-74 65 30 1E 17 0D 31 31 *ertificate0...11* + 00000090: 31 32 32 37 30 30 31 38-35 33 5A 17 0D 33 31 31 *1227001853Z..311* + 000000A0: 32 32 37 30 30 31 38 35-32 5A 30 2E 31 2C 30 2A *227001852Z0.1,0** + 000000B0: 06 03 55 04 03 13 23 41-53 55 53 54 65 4B 20 4E *..U...#ASUSTeK N* + 000000C0: 6F 74 65 62 6F 6F 6B 20-53 57 20 4B 65 79 20 43 *otebook SW Key C* + 000000D0: 65 72 74 69 66 69 63 61-74 65 30 82 01 22 30 0D *ertificate0.."0.* + 000000E0: 06 09 2A 86 48 86 F7 0D-01 01 01 05 00 03 82 01 *..*.H...........* + 000000F0: 0F 00 30 82 01 0A 02 82-01 01 00 9E 61 FA 74 2C *..0.........a.t,* + 00000100: 2A 88 17 C4 BD 77 19 0D-B3 33 27 0C 0E 94 EC B0 **....w...3'.....* + 00000110: 8B 71 B3 08 77 B7 D2 08-9D 32 4F 5C F7 0C CF E0 *.q..w....2O\....* + 00000120: 29 53 56 ED 24 91 D8 BD-53 2A 89 89 8C 74 28 AB *)SV.$...S*...t(.* + 00000130: 16 2D 4F 9B 65 FC 63 7D-ED 23 B6 97 5C 6D 04 E4 *.-O.e.c}.#..\m..* + 00000140: 15 7F DC F8 BA 6B 08 CC-C9 21 E9 B5 DE 8E 03 28 *.....k...!.....(* + 00000150: 12 63 F0 6A B6 E5 DF 1D-72 28 CC 64 D6 63 66 2F *.c.j....r(.d.cf/* + 00000160: 04 52 6A 1D 25 7D C7 BD-E0 78 FB 0C B7 37 E5 AE *.Rj.%}...x...7..* + 00000170: F7 0D D6 B5 B4 BF F5 F1-C6 82 56 78 5C A8 F3 53 *..........Vx\..S* + 00000180: 2E F5 EC 15 3F 12 62 2F-EB B6 79 79 86 AC 76 FF *....?.b/..yy..v.* + 00000190: B6 66 45 F5 33 DA DD 25-D6 A7 BF F8 D9 DB D3 F1 *.fE.3..%........* + 000001A0: FA CE 0E 22 30 D7 D4 80-02 BD D3 2C 1E EC 46 2E *..."0......,..F.* + 000001B0: 2F CA 0F 7A FA B9 5C FF-2B 16 C6 6A 6B 8D 94 64 */..z..\.+..jk..d* + 000001C0: 92 7E F9 55 EE 96 00 4D-04 2E 4B 15 ED F1 08 49 *.~.U...M..K....I* + 000001D0: 6A 07 86 69 C8 C5 64 FA-AD 2C 4F 02 50 E4 1F 83 *j..i..d..,O.P...* + 000001E0: C7 2F 19 9F E8 A5 62 D9-51 32 18 B6 83 CA 08 0A *./....b.Q2......* + 000001F0: A1 AB A7 65 70 9C 1E 48-C3 0F 49 02 03 01 00 01 *...ep..H..I.....* + 00000200: A3 63 30 61 30 5F 06 03-55 1D 01 04 58 30 56 80 *.c0a0_..U...X0V.* + 00000210: 10 00 65 11 E3 CA 0F 96-E8 8D 5B 04 A4 E7 FE CE *..e.......[.....* + 00000220: AA A1 30 30 2E 31 2C 30-2A 06 03 55 04 03 13 23 *..00.1,0*..U...#* + 00000230: 41 53 55 53 54 65 4B 20-4E 6F 74 65 62 6F 6F 6B *ASUSTeK Notebook* + 00000240: 20 53 57 20 4B 65 79 20-43 65 72 74 69 66 69 63 * SW Key Certific* + 00000250: 61 74 65 82 10 B8 E5 81-E4 DF 77 A5 BB 42 82 D5 *ate.......w..B..* + 00000260: CC FC 00 C0 71 30 0D 06-09 2A 86 48 86 F7 0D 01 *....q0...*.H....* + 00000270: 01 0B 05 00 03 82 01 01-00 31 18 F4 EE E3 72 BA *.........1....r.* + 00000280: BE 33 44 61 74 19 1F 66-AC 5C FD 1D 9A 26 75 D0 *.3Dat..f.\...&u.* + 00000290: 14 CD 68 38 B3 A8 3F 4F-B4 4A E9 1E 21 F2 C9 EE *..h8..?O.J..!...* + 000002A0: 37 96 26 BE 1D 58 9B AD-21 CE 58 79 53 D3 FF 38 *7.&..X..!.XyS..8* + 000002B0: EF 8F 22 CD 90 0E C6 32-21 75 9B 5A AB AF 08 FF *.."....2!u.Z....* + 000002C0: 05 CD 2B F8 8C E7 97 47-BB 78 E4 5F 56 47 D2 BC *..+....G.x._VG..* + 000002D0: C8 A5 95 CB 76 89 5C 65-24 02 18 06 9C 12 5F EF *....v.\e$....._.* + 000002E0: E0 5C 19 45 38 96 DF 7A-60 5D 61 BA 4D C8 7B 6E *.\.E8..z`]a.M.{n* + 000002F0: 8D 8C 6E 1D A9 E5 92 35-A2 4F 36 D3 40 AD D7 40 *..n....5.O6.@..@* + 00000300: 12 AB 6C 48 8D 18 92 E4-00 52 03 DF 14 AC 66 3F *..lH.....R....f?* + 00000310: 6A AE 42 3A 06 50 AA A5-0D 40 A7 7B EB FD 41 49 *j.B:.P...@.{..AI* + 00000320: FF EB A3 B4 50 4F F7 54-13 3B 1F 8E B4 45 04 20 *....PO.T.;...E. * + 00000330: 42 74 FE 78 3D BE 7C DB-A7 2A 2A 9D 06 48 C0 9A *Bt.x=.|..**..H..* + 00000340: 02 23 AF F2 98 07 95 DE-3B 30 73 EC 3E 73 58 8F *.#......;0s.>sX.* + 00000350: 07 53 40 96 D8 24 D9 66-80 7A 75 8D B7 39 27 10 *.S@..$.f.zu..9'.* + 00000360: 89 7A B4 53 BF 3B C2 E2-97 93 37 8A 9D 4D 23 6E *.z.S.;....7..M#n* + 00000370: AC EB 0D 53 21 4D 0B 34-13 A1 59 C0 A5 E4 94 A7 *...S!M.4..Y.....* + 00000380: 4A 87 B5 AB 15 5C 2B F0-72 82 03 00 00 00 00 00 *J....\+.r.......* + 00000390: 00 66 03 00 00 91 30 05-3B 9F 6C CC 04 B1 AC E2 *.f....0.;.l.....* + 000003A0: A5 1E 3B E5 F5 30 82 03-52 30 82 02 3A A0 03 02 *..;..0..R0..:...* + 000003B0: 01 02 02 10 DA 83 B9 90-42 2E BC 8C 44 1F 8D 8B *........B...D...* + 000003C0: 03 9A 65 A2 30 0D 06 09-2A 86 48 86 F7 0D 01 01 *..e.0...*.H.....* + 000003D0: 0B 05 00 30 31 31 2F 30-2D 06 03 55 04 03 13 26 *...011/0-..U...&* + 000003E0: 41 53 55 53 54 65 4B 20-4D 6F 74 68 65 72 42 6F *ASUSTeK MotherBo* + 000003F0: 61 72 64 20 53 57 20 4B-65 79 20 43 65 72 74 69 *ard SW Key Certi* + 00000400: 66 69 63 61 74 65 30 1E-17 0D 31 31 31 32 32 36 *ficate0...111226* + 00000410: 32 33 33 35 30 35 5A 17-0D 33 31 31 32 32 36 32 *233505Z..3112262* + 00000420: 33 33 35 30 34 5A 30 31-31 2F 30 2D 06 03 55 04 *33504Z011/0-..U.* + 00000430: 03 13 26 41 53 55 53 54-65 4B 20 4D 6F 74 68 65 *..&ASUSTeK Mothe* + 00000440: 72 42 6F 61 72 64 20 53-57 20 4B 65 79 20 43 65 *rBoard SW Key Ce* + 00000450: 72 74 69 66 69 63 61 74-65 30 82 01 22 30 0D 06 *rtificate0.."0..* + 00000460: 09 2A 86 48 86 F7 0D 01-01 01 05 00 03 82 01 0F *.*.H............* + 00000470: 00 30 82 01 0A 02 82 01-01 00 8C F6 A6 EB 77 FC *.0............w.* + 00000480: 83 8A A4 9F D5 F8 CF 3F-37 F2 6E 2D 0A 62 C5 D8 *.......?7.n-.b..* + 00000490: 9B 1D 16 0B 22 7F 29 5F-3A 26 DF 53 97 8C 78 94 *....".)_:&.S..x.* + 000004A0: 19 90 42 73 0F 85 C2 FF-A4 85 7C 81 2E 0B 51 BA *..Bs......|...Q.* + 000004B0: 56 23 27 92 3D A3 F2 DC-E2 77 84 9E 50 BE 8A EB *V#'.=....w..P...* + 000004C0: 51 34 A4 F8 EF 5D D7 51-FE 70 42 4C 42 06 EF 69 *Q4...].Q.pBLB..i* + 000004D0: 2C A2 D3 25 E1 26 57 23-85 6D D0 A7 7B C0 45 28 *,..%.&W#.m..{.E(* + 000004E0: 7E 89 D5 B4 0A EB AF 41-79 21 D2 D7 00 EC 48 F9 *~......Ay!....H.* + 000004F0: 44 F6 5B BE B6 25 24 F0-8E 2E B4 52 3E E1 0E C1 *D.[..%$....R>...* + 00000500: A4 67 EA FE E5 93 CC B9-C4 36 21 CB 54 FA AF 9D *.g.......6!.T...* + 00000510: 9C 85 78 CC E5 88 F3 84-0C 67 DB 26 69 58 CA DE *..x......g.&iX..* + 00000520: 47 34 EC CF 2F B6 49 59-B5 56 DB 58 45 7B 21 9D *G4../.IY.V.XE{!.* + 00000530: 99 0B 5F DE 57 16 A6 AB-C8 79 3F 9D 76 89 E2 09 *.._.W....y?.v...* + 00000540: F9 8D E2 63 37 FC 74 EA-73 7E 70 AC 15 16 A5 ED *...c7.t.s~p.....* + 00000550: 88 60 5F 33 ED 94 9E 0A-05 DE C7 85 C3 C1 7A 54 *.`_3..........zT* + 00000560: FB 4E CB CB E8 5E 44 7C-39 DB 2D B2 B7 6C CE CA *.N...^D|9.-..l..* + 00000570: 2F 63 9D 16 4E A6 E5 EF-D6 CF 02 03 01 00 01 A3 */c..N...........* + 00000580: 66 30 64 30 62 06 03 55-1D 01 04 5B 30 59 80 10 *f0d0b..U...[0Y..* + 00000590: 56 B0 8B 2A A7 FE CC F1-0C ED 87 62 DC D5 1D C3 *V..*.......b....* + 000005A0: A1 33 30 31 31 2F 30 2D-06 03 55 04 03 13 26 41 *.3011/0-..U...&A* + 000005B0: 53 55 53 54 65 4B 20 4D-6F 74 68 65 72 42 6F 61 *SUSTeK MotherBoa* + 000005C0: 72 64 20 53 57 20 4B 65-79 20 43 65 72 74 69 66 *rd SW Key Certif* + 000005D0: 69 63 61 74 65 82 10 DA-83 B9 90 42 2E BC 8C 44 *icate......B...D* + 000005E0: 1F 8D 8B 03 9A 65 A2 30-0D 06 09 2A 86 48 86 F7 *.....e.0...*.H..* + 000005F0: 0D 01 01 0B 05 00 03 82-01 01 00 02 CF 52 6F 0B *.............Ro.* + 00000600: 91 EB E4 3B B2 70 0C 07-2D 79 80 01 9E 4B 4D 92 *...;.p..-y...KM.* + 00000610: BB DC 9E E5 E5 31 85 E3-9A 75 ED CA DE 8C EE 28 *.....1...u.....(* + 00000620: 34 01 83 14 47 9E 3A D4-43 5B 2C C4 41 C8 40 7D *4...G.:.C[,.A.@}* + 00000630: B5 08 76 86 80 2B A8 00-9F B7 D3 B1 E6 60 5C 32 *..v..+.......`\2* + 00000640: B0 A0 01 0F BA 36 8B B7-B5 4E 87 D5 B7 0A 2C BD *.....6...N....,.* + 00000650: BC 6A 43 3C EE 76 7C 76-20 ED 39 91 A8 BF 70 1E *.jC<.v|v .9...p.* + 00000660: D6 A8 1A 3E 81 36 6B 7D-1D 8D F6 F8 AF 5B 38 53 *...>.6k}.....[8S* + 00000670: 6A 04 0D 7E AE 4D EE AB-02 D4 A4 A2 A9 CF B6 E3 *j..~.M..........* + 00000680: 66 A3 CA 4D 5D D4 18 61-4D DA 83 28 4E AA 2A AF *f..M]..aM..(N.*.* + 00000690: DA EB DF 2A 20 BD 78 80-EF D1 B0 DD 9B 77 DB C9 *...* .x......w..* + 000006A0: 25 39 4B CF A2 86 1A AC-CC 32 E7 87 D4 59 B2 03 *%9K......2...Y..* + 000006B0: C4 69 02 8F 17 C9 DE 52-CB E7 AB B8 35 C5 F8 33 *.i.....R....5..3* + 000006C0: 06 03 93 52 CF B3 68 D2-B3 5C 1C E8 19 FE 75 26 *...R..h..\....u&* + 000006D0: ED D1 65 72 13 4D 69 34-5A 9B 0C B4 E3 56 53 3C *..er.Mi4Z....VS<* + 000006E0: B4 67 27 F8 FA D3 20 DA-37 58 F6 AD E2 82 59 A2 *.g'... .7X....Y.* + 000006F0: B8 22 2F 9E 56 FE BC 17-49 1D AF A1 59 C0 A5 E4 *."/.V...I...Y...* + 00000700: 94 A7 4A 87 B5 AB 15 5C-2B F0 72 40 06 00 00 00 *..J....\+.r@....* + 00000710: 00 00 00 24 06 00 00 BD-9A FA 77 59 03 32 4D BD *...$......wY.2M.* + 00000720: 60 28 F4 E7 8F 78 4B 30-82 06 10 30 82 03 F8 A0 *`(...xK0...0....* + 00000730: 03 02 01 02 02 0A 61 08-D3 C4 00 00 00 00 00 04 *......a.........* + 00000740: 30 0D 06 09 2A 86 48 86-F7 0D 01 01 0B 05 00 30 *0...*.H........0* + 00000750: 81 91 31 0B 30 09 06 03-55 04 06 13 02 55 53 31 *..1.0...U....US1* + 00000760: 13 30 11 06 03 55 04 08-13 0A 57 61 73 68 69 6E *.0...U....Washin* + 00000770: 67 74 6F 6E 31 10 30 0E-06 03 55 04 07 13 07 52 *gton1.0...U....R* + 00000780: 65 64 6D 6F 6E 64 31 1E-30 1C 06 03 55 04 0A 13 *edmond1.0...U...* + 00000790: 15 4D 69 63 72 6F 73 6F-66 74 20 43 6F 72 70 6F *.Microsoft Corpo* + 000007A0: 72 61 74 69 6F 6E 31 3B-30 39 06 03 55 04 03 13 *ration1;09..U...* + 000007B0: 32 4D 69 63 72 6F 73 6F-66 74 20 43 6F 72 70 6F *2Microsoft Corpo* + 000007C0: 72 61 74 69 6F 6E 20 54-68 69 72 64 20 50 61 72 *ration Third Par* + 000007D0: 74 79 20 4D 61 72 6B 65-74 70 6C 61 63 65 20 52 *ty Marketplace R* + 000007E0: 6F 6F 74 30 1E 17 0D 31-31 30 36 32 37 32 31 32 *oot0...110627212* + 000007F0: 32 34 35 5A 17 0D 32 36-30 36 32 37 32 31 33 32 *245Z..2606272132* + 00000800: 34 35 5A 30 81 81 31 0B-30 09 06 03 55 04 06 13 *45Z0..1.0...U...* + 00000810: 02 55 53 31 13 30 11 06-03 55 04 08 13 0A 57 61 *.US1.0...U....Wa* + 00000820: 73 68 69 6E 67 74 6F 6E-31 10 30 0E 06 03 55 04 *shington1.0...U.* + 00000830: 07 13 07 52 65 64 6D 6F-6E 64 31 1E 30 1C 06 03 *...Redmond1.0...* + 00000840: 55 04 0A 13 15 4D 69 63-72 6F 73 6F 66 74 20 43 *U....Microsoft C* + 00000850: 6F 72 70 6F 72 61 74 69-6F 6E 31 2B 30 29 06 03 *orporation1+0)..* + 00000860: 55 04 03 13 22 4D 69 63-72 6F 73 6F 66 74 20 43 *U..."Microsoft C* + 00000870: 6F 72 70 6F 72 61 74 69-6F 6E 20 55 45 46 49 20 *orporation UEFI * + 00000880: 43 41 20 32 30 31 31 30-82 01 22 30 0D 06 09 2A *CA 20110.."0...** + 00000890: 86 48 86 F7 0D 01 01 01-05 00 03 82 01 0F 00 30 *.H.............0* + 000008A0: 82 01 0A 02 82 01 01 00-A5 08 6C 4C C7 45 09 6A *..........lL.E.j* + 000008B0: 4B 0C A4 C0 87 7F 06 75-0C 43 01 54 64 E0 16 7F *K......u.C.Td...* + 000008C0: 07 ED 92 7D 0B B2 73 BF-0C 0A C6 4A 45 61 A0 C5 *...}..s....JEa..* + 000008D0: 16 2D 96 D3 F5 2B A0 FB-4D 49 9B 41 80 90 3C B9 *.-...+..MI.A..<.* + 000008E0: 54 FD E6 BC D1 9D C4 A4-18 8A 7F 41 8A 5C 59 83 *T..........A.\Y.* + 000008F0: 68 32 BB 8C 47 C9 EE 71-BC 21 4F 9A 8A 7C FF 44 *h2..G..q.!O..|.D* + 00000900: 3F 8D 8F 32 B2 26 48 AE-75 B5 EE C9 4C 1E 4A 19 *?..2.&H.u...L.J.* + 00000910: 7E E4 82 9A 1D 78 77 4D-0C B0 BD F6 0F D3 16 D3 *~....xwM........* + 00000920: BC FA 2B A5 51 38 5D F5-FB BA DB 78 02 DB FF EC *..+.Q8]....x....* + 00000930: 0A 1B 96 D5 83 B8 19 13-E9 B6 C0 7B 40 7B E1 1F *...........{@{..* + 00000940: 28 27 C9 FA EF 56 5E 1C-E6 7E 94 7E C0 F0 44 B2 *('...V^..~.~..D.* + 00000950: 79 39 E5 DA B2 62 8B 4D-BF 38 70 E2 68 24 14 C9 *y9...b.M.8p.h$..* + 00000960: 33 A4 08 37 D5 58 69 5E-D3 7C ED C1 04 53 08 E7 *3..7.Xi^.|...S..* + 00000970: 4E B0 2A 87 63 08 61 6F-63 15 59 EA B2 2B 79 D7 *N.*.c.aoc.Y..+y.* + 00000980: 0C 61 67 8A 5B FD 5E AD-87 7F BA 86 67 4F 71 58 *.ag.[.^.....gOqX* + 00000990: 12 22 04 22 22 CE 8B EF-54 71 00 CE 50 35 58 76 *.".""...Tq..P5Xv* + 000009A0: 95 08 EE 6A B1 A2 01 D5-02 03 01 00 01 A3 82 01 *...j............* + 000009B0: 76 30 82 01 72 30 12 06-09 2B 06 01 04 01 82 37 *v0..r0...+.....7* + 000009C0: 15 01 04 05 02 03 01 00-01 30 23 06 09 2B 06 01 *.........0#..+..* + 000009D0: 04 01 82 37 15 02 04 16-04 14 F8 C1 6B B7 7F 77 *...7........k..w* + 000009E0: 53 4A F3 25 37 1D 4E A1-26 7B 0F 20 70 80 30 1D *SJ.%7.N.&{. p.0.* + 000009F0: 06 03 55 1D 0E 04 16 04-14 13 AD BF 43 09 BD 82 *..U.........C...* + 00000A00: 70 9C 8C D5 4F 31 6E D5-22 98 8A 1B D4 30 19 06 *p...O1n."....0..* + 00000A10: 09 2B 06 01 04 01 82 37-14 02 04 0C 1E 0A 00 53 *.+.....7.......S* + 00000A20: 00 75 00 62 00 43 00 41-30 0B 06 03 55 1D 0F 04 *.u.b.C.A0...U...* + 00000A30: 04 03 02 01 86 30 0F 06-03 55 1D 13 01 01 FF 04 *.....0...U......* + 00000A40: 05 30 03 01 01 FF 30 1F-06 03 55 1D 23 04 18 30 *.0....0...U.#..0* + 00000A50: 16 80 14 45 66 52 43 E1-7E 58 11 BF D6 4E 9E 23 *...EfRC.~X...N.#* + 00000A60: 55 08 3B 3A 22 6A A8 30-5C 06 03 55 1D 1F 04 55 *U.;:"j.0\..U...U* + 00000A70: 30 53 30 51 A0 4F A0 4D-86 4B 68 74 74 70 3A 2F *0S0Q.O.M.Khttp:/* + 00000A80: 2F 63 72 6C 2E 6D 69 63-72 6F 73 6F 66 74 2E 63 */crl.microsoft.c* + 00000A90: 6F 6D 2F 70 6B 69 2F 63-72 6C 2F 70 72 6F 64 75 *om/pki/crl/produ* + 00000AA0: 63 74 73 2F 4D 69 63 43-6F 72 54 68 69 50 61 72 *cts/MicCorThiPar* + 00000AB0: 4D 61 72 52 6F 6F 5F 32-30 31 30 2D 31 30 2D 30 *MarRoo_2010-10-0* + 00000AC0: 35 2E 63 72 6C 30 60 06-08 2B 06 01 05 05 07 01 *5.crl0`..+......* + 00000AD0: 01 04 54 30 52 30 50 06-08 2B 06 01 05 05 07 30 *..T0R0P..+.....0* + 00000AE0: 02 86 44 68 74 74 70 3A-2F 2F 77 77 77 2E 6D 69 *..Dhttp://www.mi* + 00000AF0: 63 72 6F 73 6F 66 74 2E-63 6F 6D 2F 70 6B 69 2F *crosoft.com/pki/* + 00000B00: 63 65 72 74 73 2F 4D 69-63 43 6F 72 54 68 69 50 *certs/MicCorThiP* + 00000B10: 61 72 4D 61 72 52 6F 6F-5F 32 30 31 30 2D 31 30 *arMarRoo_2010-10* + 00000B20: 2D 30 35 2E 63 72 74 30-0D 06 09 2A 86 48 86 F7 *-05.crt0...*.H..* + 00000B30: 0D 01 01 0B 05 00 03 82-02 01 00 35 08 42 FF 30 *...........5.B.0* + 00000B40: CC CE F7 76 0C AD 10 68-58 35 29 46 32 76 27 7C *...v...hX5)F2v'|* + 00000B50: EF 12 41 27 42 1B 4A AA-6D 81 38 48 59 13 55 F3 *..A'B.J.m.8HY.U.* + 00000B60: E9 58 34 A6 16 0B 82 AA-5D AD 82 DA 80 83 41 06 *.X4.....].....A.* + 00000B70: 8F B4 1D F2 03 B9 F3 1A-5D 1B F1 50 90 F9 B3 55 *........]..P...U* + 00000B80: 84 42 28 1C 20 BD B2 AE-51 14 C5 C0 AC 97 95 21 *.B(. ...Q......!* + 00000B90: 1C 90 DB 0F FC 77 9E 95-73 91 88 CA BD BD 52 B9 *.....w..s.....R.* + 00000BA0: 05 50 0D DF 57 9E A0 61-ED 0D E5 6D 25 D9 40 0F *.P..W..a...m%.@.* + 00000BB0: 17 40 C8 CE A3 4A C2 4D-AF 9A 12 1D 08 54 8F BD *.@...J.M.....T..* + 00000BC0: C7 BC B9 2B 3D 49 2B 1F-32 FC 6A 21 69 4F 9B C8 *...+=I+.2.j!iO..* + 00000BD0: 7E 42 34 FC 36 06 17 8B-8F 20 40 C0 B3 9A 25 75 *~B4.6.... @...%u* + 00000BE0: 27 CD C9 03 A3 F6 5D D1-E7 36 54 7A B9 50 B5 D3 *'.....]..6Tz.P..* + 00000BF0: 12 D1 07 BF BB 74 DF DC-1E 8F 80 D5 ED 18 F4 2F *.....t........./* + 00000C00: 14 16 6B 2F DE 66 8C B0-23 E5 C7 84 D8 ED EA C1 *..k/.f..#.......* + 00000C10: 33 82 AD 56 4B 18 2D F1-68 95 07 CD CF F0 72 F0 *3..VK.-.h.....r.* + 00000C20: AE BB DD 86 85 98 2C 21-4C 33 2B F0 0F 4A F0 68 *......,!L3+..J.h* + 00000C30: 87 B5 92 55 32 75 A1 6A-82 6A 3C A3 25 11 A4 ED *...U2u.j.j<.%...* + 00000C40: AD D7 04 AE CB D8 40 59-A0 84 D1 95 4C 62 91 22 *......@Y....Lb."* + 00000C50: 1A 74 1D 8C 3D 47 0E 44-A6 E4 B0 9B 34 35 B1 FA *.t..=G.D....45..* + 00000C60: B6 53 A8 2C 81 EC A4 05-71 C8 9D B8 BA E8 1B 44 *.S.,....q......D* + 00000C70: 66 E4 47 54 0E 8E 56 7F-B3 9F 16 98 B2 86 D0 68 *f.GT..V........h* + 00000C80: 3E 90 23 B5 2F 5E 8F 50-85 8D C6 8D 82 5F 41 A1 *>.#./^.P....._A.* + 00000C90: F4 2E 0D E0 99 D2 6C 75-E4 B6 69 B5 21 86 FA 07 *......lu..i.!...* + 00000CA0: D1 F6 E2 4D D1 DA AD 2C-77 53 1E 25 32 37 C7 6C *...M...,wS.%27.l* + 00000CB0: 52 72 95 86 B0 F1 35 61-6A 19 F5 B2 3B 81 50 56 *Rr....5aj...;.PV* + 00000CC0: A6 32 2D FE A2 89 F9 42-86 27 18 55 A1 82 CA 5A *.2-....B.'.U...Z* + 00000CD0: 9B F8 30 98 54 14 A6 47-96 25 2F C8 26 E4 41 94 *..0.T..G.%/.&.A.* + 00000CE0: 1A 5C 02 3F E5 96 E3 85-5B 3C 3E 3F BB 47 16 72 *.\.?....[<>?.G.r* + 00000CF0: 55 E2 25 22 B1 D9 7B E7-03 06 2A A3 F7 1E 90 46 *U.%"..{...*....F* + 00000D00: C3 00 0D D6 19 89 E3 0E-35 27 62 03 71 15 A6 EF *........5'b.q...* + 00000D10: D0 27 A0 A0 59 37 60 F8-38 94 B8 E0 78 70 F8 BA *.'..Y7`.8...xp..* + 00000D20: 4C 86 87 94 F6 E0 AE 02-45 EE 65 C2 B6 A3 7E 69 *L.......E.e...~i* + 00000D30: 16 75 07 92 9B F5 A6 BC-59 83 58 A1 59 C0 A5 E4 *.u......Y.X.Y...* + 00000D40: 94 A7 4A 87 B5 AB 15 5C-2B F0 72 07 06 00 00 00 *..J....\+.r.....* + 00000D50: 00 00 00 EB 05 00 00 BD-9A FA 77 59 03 32 4D BD *..........wY.2M.* + 00000D60: 60 28 F4 E7 8F 78 4B 30-82 05 D7 30 82 03 BF A0 *`(...xK0...0....* + 00000D70: 03 02 01 02 02 0A 61 07-76 56 00 00 00 00 00 08 *......a.vV......* + 00000D80: 30 0D 06 09 2A 86 48 86-F7 0D 01 01 0B 05 00 30 *0...*.H........0* + 00000D90: 81 88 31 0B 30 09 06 03-55 04 06 13 02 55 53 31 *..1.0...U....US1* + 00000DA0: 13 30 11 06 03 55 04 08-13 0A 57 61 73 68 69 6E *.0...U....Washin* + 00000DB0: 67 74 6F 6E 31 10 30 0E-06 03 55 04 07 13 07 52 *gton1.0...U....R* + 00000DC0: 65 64 6D 6F 6E 64 31 1E-30 1C 06 03 55 04 0A 13 *edmond1.0...U...* + 00000DD0: 15 4D 69 63 72 6F 73 6F-66 74 20 43 6F 72 70 6F *.Microsoft Corpo* + 00000DE0: 72 61 74 69 6F 6E 31 32-30 30 06 03 55 04 03 13 *ration1200..U...* + 00000DF0: 29 4D 69 63 72 6F 73 6F-66 74 20 52 6F 6F 74 20 *)Microsoft Root * + 00000E00: 43 65 72 74 69 66 69 63-61 74 65 20 41 75 74 68 *Certificate Auth* + 00000E10: 6F 72 69 74 79 20 32 30-31 30 30 1E 17 0D 31 31 *ority 20100...11* + 00000E20: 31 30 31 39 31 38 34 31-34 32 5A 17 0D 32 36 31 *1019184142Z..261* + 00000E30: 30 31 39 31 38 35 31 34-32 5A 30 81 84 31 0B 30 *019185142Z0..1.0* + 00000E40: 09 06 03 55 04 06 13 02-55 53 31 13 30 11 06 03 *...U....US1.0...* + 00000E50: 55 04 08 13 0A 57 61 73-68 69 6E 67 74 6F 6E 31 *U....Washington1* + 00000E60: 10 30 0E 06 03 55 04 07-13 07 52 65 64 6D 6F 6E *.0...U....Redmon* + 00000E70: 64 31 1E 30 1C 06 03 55-04 0A 13 15 4D 69 63 72 *d1.0...U....Micr* + 00000E80: 6F 73 6F 66 74 20 43 6F-72 70 6F 72 61 74 69 6F *osoft Corporatio* + 00000E90: 6E 31 2E 30 2C 06 03 55-04 03 13 25 4D 69 63 72 *n1.0,..U...%Micr* + 00000EA0: 6F 73 6F 66 74 20 57 69-6E 64 6F 77 73 20 50 72 *osoft Windows Pr* + 00000EB0: 6F 64 75 63 74 69 6F 6E-20 50 43 41 20 32 30 31 *oduction PCA 201* + 00000EC0: 31 30 82 01 22 30 0D 06-09 2A 86 48 86 F7 0D 01 *10.."0...*.H....* + 00000ED0: 01 01 05 00 03 82 01 0F-00 30 82 01 0A 02 82 01 *.........0......* + 00000EE0: 01 00 DD 0C BB A2 E4 2E-09 E3 E7 C5 F7 96 69 BC *..............i.* + 00000EF0: 00 21 BD 69 33 33 EF AD-04 CB 54 80 EE 06 83 BB *.!.i33....T.....* + 00000F00: C5 20 84 D9 F7 D2 8B F3-38 B0 AB A4 AD 2D 7C 62 *. ......8....-|b* + 00000F10: 79 05 FF E3 4A 3F 04 35-20 70 E3 C4 E7 6B E0 9C *y...J?.5 p...k..* + 00000F20: C0 36 75 E9 8A 31 DD 8D-70 E5 DC 37 B5 74 46 96 *.6u..1..p..7.tF.* + 00000F30: 28 5B 87 60 23 2C BF DC-47 A5 67 F7 51 27 9E 72 *([.`#,..G.g.Q'.r* + 00000F40: EB 07 A6 C9 B9 1E 3B 53-35 7C E5 D3 EC 27 B9 87 *......;S5|...'..* + 00000F50: 1C FE B9 C9 23 09 6F A8-46 91 C1 6E 96 3C 41 D3 *....#.o.F..n.* + 000010F0: 68 74 74 70 3A 2F 2F 77-77 77 2E 6D 69 63 72 6F *http://www.micro* + 00001100: 73 6F 66 74 2E 63 6F 6D-2F 70 6B 69 2F 63 65 72 *soft.com/pki/cer* + 00001110: 74 73 2F 4D 69 63 52 6F-6F 43 65 72 41 75 74 5F *ts/MicRooCerAut_* + 00001120: 32 30 31 30 2D 30 36 2D-32 33 2E 63 72 74 30 0D *2010-06-23.crt0.* + 00001130: 06 09 2A 86 48 86 F7 0D-01 01 0B 05 00 03 82 02 *..*.H...........* + 00001140: 01 00 14 FC 7C 71 51 A5-79 C2 6E B2 EF 39 3E BC *....|qQ.y.n..9>.* + 00001150: 3C 52 0F 6E 2B 3F 10 13-73 FE A8 68 D0 48 A6 34 *.\`* + 00001220: EC DF 03 10 A8 D3 09 E9-F4 F6 96 85 B6 7F 51 88 *..............Q.* + 00001230: 66 47 19 8D A2 B0 12 3D-81 2A 68 05 77 BB 91 4C *fG.....=.*h.w..L* + 00001240: 62 7B B6 C1 07 C7 BA 7A-87 34 03 0E 4B 62 7A 99 *b{.....z.4..Kbz.* + 00001250: E9 CA FC CE 4A 37 C9 2D-A4 57 7C 1C FE 3D DC B8 *....J7.-.W|..=..* + 00001260: 0F 5A FA D6 C4 B3 02 85-02 3A EA B3 D9 6E E4 69 *.Z.......:...n.i* + 00001270: 21 37 DE 81 D1 F6 75 19-05 67 D3 93 57 5E 29 1B *!7....u..g..W^).* + 00001280: 39 C8 EE 2D E1 CD E4 45-73 5B D0 D2 CE 7A AB 16 *9..-...Es[...z..* + 00001290: 19 82 46 58 D0 5E 9D 81-B3 67 AF 6C 35 F2 BC E5 *..FX.^...g.l5...* + 000012A0: 3F 24 E2 35 A2 0A 75 06-F6 18 56 99 D4 78 2C D1 *?$.5..u...V..x,.* + 000012B0: 05 1B EB D0 88 01 9D AA-10 F1 05 DF BA 7E 2C 63 *.............~,c* + 000012C0: B7 06 9B 23 21 C4 F9 78-6C E2 58 17 06 36 2B 91 *...#!..xl.X..6+.* + 000012D0: 12 03 CC A4 D9 F2 2D BA-F9 94 9D 40 ED 18 45 F1 *......-....@..E.* + 000012E0: CE 8A 5C 6B 3E AB 03 D3-70 18 2A 0A 6A E0 5F 47 *..\k>...p.*.j._G* + 000012F0: D1 D5 63 0A 32 F2 AF D7-36 1F 2A 70 5A E5 42 59 *..c.2...6.*pZ.BY* + 00001300: 08 71 4B 57 BA 7E 83 81-F0 21 3C F4 1C C1 C5 B9 *.qKW.~...!<.....* + 00001310: 90 93 0E 88 45 93 86 E9-B1 20 99 BE 98 CB C5 95 *....E.... ......* + 00001320: A4 5D 62 D6 A0 63 08 20-BD 75 10 77 7D 3D F3 45 *.]b..c. .u.w}=.E* + 00001330: B9 9F 97 9F CB 57 80 6F-33 A9 04 CF 77 A4 62 1C *.....W.o3...w.b.* + 00001340: 59 7E A1 59 C0 A5 E4 94-A7 4A 87 B5 AB 15 5C 2B *Y~.Y.....J....\+* + 00001350: F0 72 64 04 00 00 00 00-00 00 48 04 00 00 E4 0A *.rd.......H.....* + 00001360: C4 6D E8 2E 4C 9C A3 14-0F C7 B2 00 87 10 30 82 *.m..L.........0.* + 00001370: 04 34 30 82 03 1C A0 03-02 01 02 02 09 00 B9 41 *.40............A* + 00001380: 24 A0 18 2C 92 67 30 0D-06 09 2A 86 48 86 F7 0D *$..,.g0...*.H...* + 00001390: 01 01 0B 05 00 30 81 84-31 0B 30 09 06 03 55 04 *.....0..1.0...U.* + 000013A0: 06 13 02 47 42 31 14 30-12 06 03 55 04 08 0C 0B *...GB1.0...U....* + 000013B0: 49 73 6C 65 20 6F 66 20-4D 61 6E 31 10 30 0E 06 *Isle of Man1.0..* + 000013C0: 03 55 04 07 0C 07 44 6F-75 67 6C 61 73 31 17 30 *.U....Douglas1.0* + 000013D0: 15 06 03 55 04 0A 0C 0E-43 61 6E 6F 6E 69 63 61 *...U....Canonica* + 000013E0: 6C 20 4C 74 64 2E 31 34-30 32 06 03 55 04 03 0C *l Ltd.1402..U...* + 000013F0: 2B 43 61 6E 6F 6E 69 63-61 6C 20 4C 74 64 2E 20 *+Canonical Ltd. * + 00001400: 4D 61 73 74 65 72 20 43-65 72 74 69 66 69 63 61 *Master Certifica* + 00001410: 74 65 20 41 75 74 68 6F-72 69 74 79 30 1E 17 0D *te Authority0...* + 00001420: 31 32 30 34 31 32 31 31-31 32 35 31 5A 17 0D 34 *120412111251Z..4* + 00001430: 32 30 34 31 31 31 31 31-32 35 31 5A 30 81 84 31 *20411111251Z0..1* + 00001440: 0B 30 09 06 03 55 04 06-13 02 47 42 31 14 30 12 *.0...U....GB1.0.* + 00001450: 06 03 55 04 08 0C 0B 49-73 6C 65 20 6F 66 20 4D *..U....Isle of M* + 00001460: 61 6E 31 10 30 0E 06 03-55 04 07 0C 07 44 6F 75 *an1.0...U....Dou* + 00001470: 67 6C 61 73 31 17 30 15-06 03 55 04 0A 0C 0E 43 *glas1.0...U....C* + 00001480: 61 6E 6F 6E 69 63 61 6C-20 4C 74 64 2E 31 34 30 *anonical Ltd.140* + 00001490: 32 06 03 55 04 03 0C 2B-43 61 6E 6F 6E 69 63 61 *2..U...+Canonica* + 000014A0: 6C 20 4C 74 64 2E 20 4D-61 73 74 65 72 20 43 65 *l Ltd. Master Ce* + 000014B0: 72 74 69 66 69 63 61 74-65 20 41 75 74 68 6F 72 *rtificate Author* + 000014C0: 69 74 79 30 82 01 22 30-0D 06 09 2A 86 48 86 F7 *ity0.."0...*.H..* + 000014D0: 0D 01 01 01 05 00 03 82-01 0F 00 30 82 01 0A 02 *...........0....* + 000014E0: 82 01 01 00 BF 5B 3A 16-74 EE 21 5D AE 61 ED 9D *.....[:.t.!].a..* + 000014F0: 56 AC BD DE DE 72 F3 DD-7E 2D 4C 62 0F AC C0 6D *V....r..~-Lb...m* + 00001500: 48 08 11 CF 8D 8B FB 61-1F 27 CC 11 6E D9 55 3D *H......a.'..n.U=* + 00001510: 39 54 EB 40 3B B1 BB E2-85 34 79 CA F7 7B BF BA *9T.@;....4y..{..* + 00001520: 7A C8 10 2D 19 7D AD 59-CF A6 D4 E9 4E 0F DA AE *z..-.}.Y....N...* + 00001530: 52 EA 4C 9E 90 CE C6 99-0D 4E 67 65 78 5D F9 D1 *R.L......Ngex]..* + 00001540: D5 38 4A 4A 7A 8F 93 9C-7F 1A A3 85 DB CE FA 8B *.8JJz...........* + 00001550: F7 C2 A2 21 2D 9B 54 41-35 10 57 13 8D 6C BC 29 *...!-.TA5.W..l.)* + 00001560: 06 50 4A 7E EA 99 A9 68-A7 3B C7 07 1B 32 9E A0 *.PJ~...h.;...2..* + 00001570: 19 87 0E 79 BB 68 99 2D-7E 93 52 E5 F6 EB C9 9B *...y.h.-~.R.....* + 00001580: F9 2B ED B8 68 49 BC D9-95 50 40 5B C5 B2 71 AA *.+..hI...P@[..q.* + 00001590: EB 5C 57 DE 71 F9 40 0A-DD 5B AC 1E 84 2D 50 1A *.\W.q.@..[...-P.* + 000015A0: 52 D6 E1 F3 6B 6E 90 64-4F 5B B4 EB 20 E4 61 10 *R...kn.dO[.. .a.* + 000015B0: DA 5A F0 EA E4 42 D7 01-C4 FE 21 1F D9 B9 C0 54 *.Z...B....!....T* + 000015C0: 95 42 81 52 72 1F 49 64-7A C8 6C 24 F1 08 70 0B *.B.Rr.Idz.l$..p.* + 000015D0: 4D A5 A0 32 D1 A0 1C 57-A8 4D E3 AF A5 8E 05 05 *M..2...W.M......* + 000015E0: 3E 10 43 A1 02 03 01 00-01 A3 81 A6 30 81 A3 30 *>.C.........0..0* + 000015F0: 1D 06 03 55 1D 0E 04 16-04 14 AD 91 99 0B C2 2A *...U...........** + 00001600: B1 F5 17 04 8C 23 B6 65-5A 26 8E 34 5A 63 30 1F *.....#.eZ&.4Zc0.* + 00001610: 06 03 55 1D 23 04 18 30-16 80 14 AD 91 99 0B C2 *..U.#..0........* + 00001620: 2A B1 F5 17 04 8C 23 B6-65 5A 26 8E 34 5A 63 30 **.....#.eZ&.4Zc0* + 00001630: 0F 06 03 55 1D 13 01 01-FF 04 05 30 03 01 01 FF *...U.......0....* + 00001640: 30 0B 06 03 55 1D 0F 04-04 03 02 01 86 30 43 06 *0...U........0C.* + 00001650: 03 55 1D 1F 04 3C 30 3A-30 38 A0 36 A0 34 86 32 *.U...<0:08.6.4.2* + 00001660: 68 74 74 70 3A 2F 2F 77-77 77 2E 63 61 6E 6F 6E *http://www.canon* + 00001670: 69 63 61 6C 2E 63 6F 6D-2F 73 65 63 75 72 65 2D *ical.com/secure-* + 00001680: 62 6F 6F 74 2D 6D 61 73-74 65 72 2D 63 61 2E 63 *boot-master-ca.c* + 00001690: 72 6C 30 0D 06 09 2A 86-48 86 F7 0D 01 01 0B 05 *rl0...*.H.......* + 000016A0: 00 03 82 01 01 00 3F 7D-F6 76 A5 B3 83 B4 2B 7A *......?}.v....+z* + 000016B0: D0 6D 52 1A 03 83 C4 12-A7 50 9C 47 92 CC C0 94 *.mR......P.G....* + 000016C0: 77 82 D2 AE 57 B3 99 04-F5 32 3A C6 55 1D 07 DB *w...W....2:.U...* + 000016D0: 12 A9 56 FA D8 D4 76 20-EB E4 C3 51 DB 9A 5C 9C *..V...v ...Q..\.* + 000016E0: 92 3F 18 73 DA 94 6A A1-99 38 8C A4 88 6D C1 FC *.?.s..j..8...m..* + 000016F0: 39 71 D0 74 76 16 03 3E-56 23 35 D5 55 47 5B 1A *9q.tv..>V#5.UG[.* + 00001700: 1D 41 C2 D3 12 4C DC FF-AE 0A 92 9C 62 0A 17 01 *.A...L......b...* + 00001710: 9C 73 E0 5E B1 FD BC D6-B5 19 11 7A 7E CD 3E 03 *.s.^.......z~.>.* + 00001720: 7E 66 DB 5B A8 C9 39 48-51 FF 53 E1 9C 31 53 91 *~f.[..9HQ.S..1S.* + 00001730: 1B 3B 10 75 03 17 BA E6-81 02 80 94 70 4C 46 B7 *.;.u........pLF.* + 00001740: 94 B0 3D 15 CD 1F 8E 02-E0 68 02 8F FB F9 47 1D *..=......h....G.* + 00001750: 7D A2 01 C6 07 51 C4 9A-CC ED DD CF A3 5D ED 92 *}....Q.......]..* + 00001760: BB BE D1 FD E6 EC 1F 33-51 73 04 BE 3C 72 B0 7D *.......3Qs.....* + 00001790: 14 DB CE 03 0E 0B 66 C4-1C 6D BD B8 27 77 C1 42 *......f..m..'w.B* + 000017A0: 94 BD FC 6A 0A BC *...j..* +Variable RT+BS 'EFIGlobalVariable:dbtDefault' DataSize = 0x4C + 00000000: 26 16 C4 C1 4C 50 92 40-AC A9 41 F9 36 93 43 28 *&...LP.@..A.6.C(* + 00000010: 4C 00 00 00 00 00 00 00-30 00 00 00 00 00 00 00 *L.......0.......* + 00000020: 00 00 00 00 00 00 00 00-00 00 00 00 40 2C 75 0B *............@,u.* + 00000030: 86 70 FB 7E C7 3E 94 07-B0 73 2C 57 AD 5C B5 49 *.p.~.>...s,W.\.I* + 00000040: 07 AE F8 1E 3B 21 80 EA-4F CE 7B 2B *....;!..O.{+* +Variable RT+BS 'EFIGlobalVariable:dbxDefault' DataSize = 0xE8C + 00000000: 26 16 C4 C1 4C 50 92 40-AC A9 41 F9 36 93 43 28 *&...LP.@..A.6.C(* + 00000010: 8C 0E 00 00 00 00 00 00-30 00 00 00 BD 9A FA 77 *........0......w* + 00000020: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 80 B4 D9 69 *Y.2M.`(...xK...i* + 00000030: 31 BF 0D 02 FD 91 A6 1E-19 D1 4F 1D A4 52 E6 6D *1.........O..R.m* + 00000040: B2 40 8C A8 60 4D 41 1F-92 65 9F 0A BD 9A FA 77 *.@..`MA..e.....w* + 00000050: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B F5 2F 83 A3 *Y.2M.`(...xK./..* + 00000060: FA 9C FB D6 92 0F 72 28-24 DB E4 03 45 34 D2 5B *......r($...E4.[* + 00000070: 85 07 24 6B 3B 95 7D AC-6E 1B CE 7A BD 9A FA 77 *..$k;.}.n..z...w* + 00000080: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B C5 D9 D8 A1 *Y.2M.`(...xK....* + 00000090: 86 E2 C8 2D 09 AF AA 2A-6F 7F 2E 73 87 0D 3E 64 *...-...*o..s..>d* + 000000A0: F7 2C 4E 08 EF 67 79 6A-84 0F 0F BD BD 9A FA 77 *.,N..gyj.......w* + 000000B0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 36 33 84 D1 *Y.2M.`(...xK63..* + 000000C0: 4D 1F 2E 0B 78 15 62 64-84 C4 59 AD 57 A3 18 EF *M...x.bd..Y.W...* + 000000D0: 43 96 26 60 48 D0 58 C5-A1 9B BF 76 BD 9A FA 77 *C.&`H.X....v...w* + 000000E0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 1A EC 84 B8 *Y.2M.`(...xK....* + 000000F0: 4B 6C 65 A5 12 20 A9 BE-71 81 96 52 30 21 0D 62 *Kle.. ..q..R0!.b* + 00000100: D6 D3 3C 48 99 9C 6B 29-5A 2B 0A 06 BD 9A FA 77 *....h2.....'* + 00000280: 25 27 DF B6 3D 49 D2 95-72 A6 F4 4C BD 9A FA 77 *%'..=I..r..L...w* + 00000290: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 07 5E EA 06 *Y.2M.`(...xK.^..* + 000002A0: 05 89 54 8B A0 60 B2 FE-ED 10 DA 3C 20 C7 FE 9B *..T..`.....< ...* + 000002B0: 17 CD 02 6B 94 E8 A6 83-B8 11 52 38 BD 9A FA 77 *...k......R8...w* + 000002C0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 07 E6 C6 A8 *Y.2M.`(...xK....* + 000002D0: 58 64 6F B1 EF C6 79 03-FE 28 B1 16 01 1F 23 67 *Xdo...y..(....#g* + 000002E0: FE 92 E6 BE 2B 36 99 9E-FF 39 D0 9E BD 9A FA 77 *....+6...9.....w* + 000002F0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 09 DF 5F 4E *Y.2M.`(...xK.._N* + 00000300: 51 12 08 EC 78 B9 6D 12-D0 81 25 FD B6 03 86 8D *Q...x.m...%.....* + 00000310: E3 9F 6F 72 92 78 52 59-9B 65 9C 26 BD 9A FA 77 *..or.xRY.e.&...w* + 00000320: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 0B BB 43 92 *Y.2M.`(...xK..C.* + 00000330: DA AC 7A B8 9B 30 A4 AC-65 75 31 B9 7B FA AB 04 *..z..0..eu1.{...* + 00000340: F9 0B 0D AF E5 F9 B6 EB-90 A0 63 74 BD 9A FA 77 *..........ct...w* + 00000350: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 0C 18 93 39 *Y.2M.`(...xK...9* + 00000360: 76 2D F3 36 AB 3D D0 06-A4 63 DF 71 5A 39 CF B0 *v-.6.=...c.qZ9..* + 00000370: F4 92 46 5C 60 0E 6C 6B-D7 BD 89 8C BD 9A FA 77 *..F\`.lk.......w* + 00000380: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 0D 0D BE CA *Y.2M.`(...xK....* + 00000390: 6F 29 EC A0 6F 33 1A 7D-72 E4 88 4B 12 09 7F B3 *o)..o3.}r..K....* + 000003A0: 48 98 3A 2A 14 A0 D7 3F-4F 10 14 0F BD 9A FA 77 *H.:*...?O......w* + 000003B0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 0D C9 F3 FB *Y.2M.`(...xK....* + 000003C0: 99 96 21 48 C3 CA 83 36-32 75 8D 3E D4 FC 8D 0B *..!H...62u.>....* + 000003D0: 00 07 B9 5B 31 E6 52 8F-2A CD 5B FC BD 9A FA 77 *...[1.R.*.[....w* + 000003E0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 10 6F AC EA *Y.2M.`(...xK.o..* + 000003F0: CF EC FD 4E 30 3B 74 F4-80 A0 80 98 E2 D0 80 2B *...N0;t........+* + 00000400: 93 6F 8E C7 74 CE 21 F3-16 86 68 9C BD 9A FA 77 *.o..t.!...h....w* + 00000410: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 17 4E 3A 0B *Y.2M.`(...xK.N:.* + 00000420: 5B 43 C6 A6 07 BB D3 40-4F 05 34 1E 3D CF 39 62 *[C.....@O.4.=.9b* + 00000430: 67 CE 94 F8 B5 0E 2E 23-A9 DA 92 0C BD 9A FA 77 *g......#.......w* + 00000440: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 18 33 34 29 *Y.2M.`(...xK.34)* + 00000450: FF 05 62 ED 9F 97 03 3E-11 48 DC EE E5 2D BE 2E *..b....>.H...-..* + 00000460: 49 6D 54 10 B5 CF D6 C8-64 D2 D1 0F BD 9A FA 77 *ImT.....d......w* + 00000470: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 2B 99 CF 26 *Y.2M.`(...xK+..&* + 00000480: 42 2E 92 FE 36 5F BF 4B-C3 0D 27 08 6C 9E E1 4B *B...6_.K..'.l..K* + 00000490: 7A 6F FF 44 FB 2F 6B 90-01 69 99 39 BD 9A FA 77 *zo.D./k..i.9...w* + 000004A0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 2B BF 2C A7 *Y.2M.`(...xK+.,.* + 000004B0: B8 F1 D9 1F 27 EE 52 B6-FB 2A 5D D0 49 B8 5A 2B *....'.R..*].I.Z+* + 000004C0: 9B 52 9C 5D 66 62 06 81-04 B0 55 F8 BD 9A FA 77 *.R.]fb....U....w* + 000004D0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 2C 73 D9 33 *Y.2M.`(...xK,s.3* + 000004E0: 25 BA 6D CB E5 89 D4 A4-C6 3C 5B 93 55 59 EF 92 *%.m......<[.UY..* + 000004F0: FB F0 50 ED 50 C4 E2 08-52 06 F1 7D BD 9A FA 77 *..P.P...R..}...w* + 00000500: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 2E 70 91 67 *Y.2M.`(...xK.p.g* + 00000510: 86 A6 F7 73 51 1F A7 18-1F AB 0F 1D 70 B5 57 C6 *...sQ.......p.W.* + 00000520: 32 2E A9 23 B2 A8 D3 B9-2B 51 AF 7D BD 9A FA 77 *2..#....+Q.}...w* + 00000530: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 30 66 28 FA *Y.2M.`(...xK0f(.* + 00000540: 54 77 30 57 28 BA 4A 46-7D E7 D0 38 7A 54 F5 69 *Tw0W(.JF}..8zT.i* + 00000550: D3 76 9F CE 5E 75 EC 89-D2 8D 15 93 BD 9A FA 77 *.v..^u.........w* + 00000560: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 36 08 ED BA *Y.2M.`(...xK6...* + 00000570: F5 AD 0F 41 A4 14 A1 77-7A BF 2F AF 5E 67 03 34 *...A...wz./.^g.4* + 00000580: 67 5E C3 99 5E 69 35 82-9E 0C AA D2 BD 9A FA 77 *g^..^i5........w* + 00000590: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 38 41 D2 21 *Y.2M.`(...xK8A.!* + 000005A0: 36 8D 15 83 D7 5C 0A 02-E6 21 60 39 4D 6C 4E 0A *6....\...!`9MlN.* + 000005B0: 67 60 B6 F6 07 B9 03 62-BC 85 5B 02 BD 9A FA 77 *g`.....b..[....w* + 000005C0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 3F CE 9B 9F *Y.2M.`(...xK?...* + 000005D0: DF 3E F0 9D 54 52 B0 F9-5E E4 81 C2 B7 F0 6D 74 *.>..TR..^.....mt* + 000005E0: 3A 73 79 71 55 8E 70 13-6A CE 3E 73 BD 9A FA 77 *:syqU.p.j.>s...w* + 000005F0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 43 97 DA CA *Y.2M.`(...xKC...* + 00000600: 83 9E 7F 63 07 7C B5 0C-92 DF 43 BC 2D 2F B2 A8 *...c.|....C.-/..* + 00000610: F5 9F 26 FC 7A 0E 4B D4-D9 75 16 92 BD 9A FA 77 *..&.z.K..u.....w* + 00000620: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 47 CC 08 61 *Y.2M.`(...xKG..a* + 00000630: 27 E2 06 9A 86 E0 3A 6B-EF 2C D4 10 F8 C5 5A 6D *'.....:k.,....Zm* + 00000640: 6B DB 36 21 68 C3 1B 2C-E3 2A 5A DF BD 9A FA 77 *k.6!h..,.*Z....w* + 00000650: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 51 88 31 FE *Y.2M.`(...xKQ.1.* + 00000660: 73 82 B5 14 D0 3E 15 C6-21 22 8B 8A B6 54 79 BD *s....>..!"...Ty.* + 00000670: 0C BF A3 C5 C1 D0 F4 8D-9C 30 61 35 BD 9A FA 77 *.........0a5...w* + 00000680: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 5A E9 49 EA *Y.2M.`(...xKZ.I.* + 00000690: 88 55 EB 93 E4 39 DB C6-5B DA 2E 42 85 2C 2F DF *.U...9..[..B.,/.* + 000006A0: 67 89 FA 14 67 36 E3 C3-41 0F 2B 5C BD 9A FA 77 *g...g6..A.+\...w* + 000006B0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 6B 1D 13 80 *Y.2M.`(...xKk...* + 000006C0: 78 E4 41 8A A6 8D EB 7B-B3 5E 06 60 92 CF 47 9E *x.A....{.^.`..G.* + 000006D0: EB 8C E4 CD 12 E7 D0 72-CC B4 2F 66 BD 9A FA 77 *.......r../f...w* + 000006E0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 6C 88 54 47 *Y.2M.`(...xKl.TG* + 000006F0: 8D D5 59 E2 93 51 B8 26-C0 6C B8 BF EF 2B 94 AD *..Y..Q.&.l...+..* + 00000700: 35 38 35 87 72 D1 93 F8-2E D1 CA 11 BD 9A FA 77 *585.r..........w* + 00000710: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 6F 14 28 FF *Y.2M.`(...xKo.(.* + 00000720: 71 C9 DB 0E D5 AF 1F 2E-7B BF CB AB 64 7C C2 65 *q.......{...d|.e* + 00000730: DD F5 B2 93 CD B6 26 F5-0A 3A 78 5E BD 9A FA 77 *......&..:x^...w* + 00000740: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 71 F2 90 6F *Y.2M.`(...xKq..o* + 00000750: D2 22 49 7E 54 A3 46 62-AB 24 97 FC C8 10 20 77 *."I~T.Fb.$.... w* + 00000760: 0F F5 13 68 E9 E3 D9 BF-CB FD 63 75 BD 9A FA 77 *...h......cu...w* + 00000770: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 72 6B 3E B6 *Y.2M.`(...xKrk>.* + 00000780: 54 04 6A 30 F3 F8 3D 9B-96 CE 03 F6 70 E9 A8 06 *T.j0..=.....p...* + 00000790: D1 70 8A 03 71 E6 2D C4-9D 2C 23 C1 BD 9A FA 77 *.p..q.-..,#....w* + 000007A0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 72 E0 BD 18 *Y.2M.`(...xKr...* + 000007B0: 67 CF 5D 9D 56 AB 15 8A-DF 3B DD BC 82 BF 32 A8 *g.].V....;....2.* + 000007C0: D8 AA 1D 8C 5E 2F 6D F2-94 28 D6 D8 BD 9A FA 77 *....^/m..(.....w* + 000007D0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 78 27 AF 99 *Y.2M.`(...xKx'..* + 000007E0: 36 2C FA F0 71 7D AD E4-B1 BF E0 43 8A D1 71 C1 *6,..q}.....C..q.* + 000007F0: 5A DD C2 48 B7 5B F8 CA-A4 4B B2 C5 BD 9A FA 77 *Z..H.[...K.....w* + 00000800: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 81 A8 B9 65 *Y.2M.`(...xK...e* + 00000810: BB 84 D3 87 6B 94 29 A9-54 81 CC 95 53 18 CF AA *....k.).T...S...* + 00000820: 14 12 D8 08 C8 A3 3B FD-33 FF F0 E4 BD 9A FA 77 *......;.3......w* + 00000830: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 82 DB 3B CE *Y.2M.`(...xK..;.* + 00000840: B4 F6 08 43 CE 9D 97 C3-D1 87 CD 9B 59 41 CD 3D *...C........YA.=* + 00000850: E8 10 0E 58 6F 2B DA 56-37 57 5F 67 BD 9A FA 77 *...Xo+.V7W_g...w* + 00000860: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 89 5A 97 85 *Y.2M.`(...xK.Z..* + 00000870: F6 17 CA 1D 7E D4 4F C1-A1 47 0B 71 F3 F1 22 38 *....~.O..G.q.."8* + 00000880: 62 D9 FF 9D CC 3A E2 DF-92 16 3D AF BD 9A FA 77 *b....:....=....w* + 00000890: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 8A D6 48 59 *Y.2M.`(...xK..HY* + 000008A0: F1 95 B5 F5 8D AF AA 94-0B 6A 61 67 AC D6 7A 88 *.........jag..z.* + 000008B0: 6E 8F 46 93 64 17 72 21-C5 59 45 B9 BD 9A FA 77 *n.F.d.r!.YE....w* + 000008C0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 8B F4 34 B4 *Y.2M.`(...xK..4.* + 000008D0: 9E 00 CC F7 15 02 A2 CD-90 08 65 CB 01 EC 3B 3D *..........e...;=* + 000008E0: A0 3C 35 BE 50 5F DF 7B-D5 63 F5 21 BD 9A FA 77 *.<5.P_.{.c.!...w* + 000008F0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 8D 8E A2 89 *Y.2M.`(...xK....* + 00000900: CF E7 0A 1C 07 AB 73 65-CB 28 EE 51 ED D3 3C F2 *......se.(.Q..<.* + 00000910: 50 6D E8 88 FB AD D6 0E-BF 80 48 1C BD 9A FA 77 *Pm........H....w* + 00000920: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 99 98 D3 63 *Y.2M.`(...xK...c* + 00000930: C4 91 BE 16 BD 74 BA 10-B9 4D 92 91 00 16 11 73 *.....t...M.....s* + 00000940: 6F DC A6 43 A3 66 64 BC-0F 31 5A 42 BD 9A FA 77 *o..C.fd..1ZB...w* + 00000950: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 9E 4A 69 17 *Y.2M.`(...xK.Ji.* + 00000960: 31 61 68 2E 55 FD E8 FE-F5 60 EB 88 EC 1F FE DC *1ah.U....`......* + 00000970: AF 04 00 1F 66 C0 CA F7-07 B2 B7 34 BD 9A FA 77 *....f......4...w* + 00000980: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B A6 B5 15 1F *Y.2M.`(...xK....* + 00000990: 36 55 D3 A2 AF 0D 47 27-59 79 6B E4 A4 20 0E 54 *6U....G'Yyk.. .T* + 000009A0: 95 A7 D8 69 75 4C 48 48-85 74 08 A7 BD 9A FA 77 *...iuLHH.t.....w* + 000009B0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B A7 F3 2F 50 *Y.2M.`(...xK../P* + 000009C0: 8D 4E B0 FE AD 9A 08 7E-F9 4E D1 BA 0A EC 5D E6 *.N.....~.N....].* + 000009D0: F7 EF 6F F0 A6 2B 93 BE-DF 5D 45 8D BD 9A FA 77 *..o..+...]E....w* + 000009E0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B AD 68 26 E1 *Y.2M.`(...xK.h&.* + 000009F0: 94 6D 26 D3 EA F3 68 5C-88 D9 7D 85 DE 3B 4D CB *.m&...h\..}..;M.* + 00000A00: 3D 0E E2 AE 81 C7 05 60-D1 3C 57 20 BD 9A FA 77 *=......`...$Q* + 00000C10: 3F BC 65 59 57 D7 35 FA-29 F5 40 CE BD 9A FA 77 *?.eYW.5.).@....w* + 00000C20: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B D8 CB EB 97 *Y.2M.`(...xK....* + 00000C30: 35 F5 67 2B 36 7E 4F 96-CD C7 49 69 61 5D 17 07 *5.g+6~O...Iia]..* + 00000C40: 4A E9 6C 72 4D 42 CE 02-16 F8 F3 FA BD 9A FA 77 *J.lrMB.........w* + 00000C50: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B E9 2C 22 EB *Y.2M.`(...xK.,".* + 00000C60: 3B 56 42 D6 5C 1E C2 CA-F2 47 D2 59 47 38 EE BB *;VB.\....G.YG8..* + 00000C70: 7F B3 84 1A 44 95 6F 59-E2 B0 D1 FA BD 9A FA 77 *....D.oY.......w* + 00000C80: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B FD DD 6E 3D *Y.2M.`(...xK..n=* + 00000C90: 29 EA 84 C7 74 3D AD 4A-1B DB C7 00 B5 FE C1 B3 *)...t=.J........* + 00000CA0: 91 F9 32 40 90 86 AC C7-1D D6 DB D8 BD 9A FA 77 *..2@...........w* + 00000CB0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B FE 63 A8 4F *Y.2M.`(...xK.c.O* + 00000CC0: 78 2C C9 D3 FC F2 CC F9-FC 11 FB D0 37 60 87 87 *x,..........7`..* + 00000CD0: 58 D2 62 85 ED 12 66 9B-DC 6E 6D 01 BD 9A FA 77 *X.b...f..nm....w* + 00000CE0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B FE CF B2 32 *Y.2M.`(...xK...2* + 00000CF0: D1 2E 99 4B 6D 48 5D 2C-71 67 72 8A A5 52 59 84 *...KmH],qgr..RY.* + 00000D00: AD 5C A6 1E 75 16 22 1F-07 9A 14 36 BD 9A FA 77 *.\..u."....6...w* + 00000D10: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B CA 17 1D 61 *Y.2M.`(...xK...a* + 00000D20: 4A 8D 7E 12 1C 93 94 8C-D0 FE 55 D3 99 81 F9 D1 *J.~.......U.....* + 00000D30: 1A A9 6E 03 45 0A 41 52-27 C2 C6 5B BD 9A FA 77 *..n.E.AR'..[...w* + 00000D40: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 55 B9 9B 0D *Y.2M.`(...xKU...* + 00000D50: E5 3D BC FE 48 5A A9 C7-37 CF 3F B6 16 EF 3D 91 *.=..HZ..7.?...=.* + 00000D60: FA B5 99 AA 7C AB 19 ED-A7 63 B5 BA BD 9A FA 77 *....|....c.....w* + 00000D70: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 77 DD 19 0F *Y.2M.`(...xKw...* + 00000D80: A3 0D 88 FF 5E 3B 01 1A-0A E6 1E 62 09 78 0C 13 *....^;.....b.x..* + 00000D90: 0B 53 5E CB 87 E6 F0 88-8A 0B 6B 2F BD 9A FA 77 *.S^.......k/...w* + 00000DA0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B C8 3C B1 39 *Y.2M.`(...xK.<.9* + 00000DB0: 22 AD 99 F5 60 74 46 75-DD 37 CC 94 DC AD 5A 1F *"...`tFu.7....Z.* + 00000DC0: CB A6 47 2F EE 34 11 71-D9 39 E8 84 BD 9A FA 77 *..G/.4.q.9.....w* + 00000DD0: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 3B 02 87 53 *Y.2M.`(...xK;..S* + 00000DE0: 3E 0C C3 D0 EC 1A A8 23-CB F0 A9 41 AA D8 72 15 *>......#...A..r.* + 00000DF0: 79 D1 C4 99 80 2D D1 C3-A6 36 B8 A9 BD 9A FA 77 *y....-...6.....w* + 00000E00: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 93 9A EE F4 *Y.2M.`(...xK....* + 00000E10: F5 FA 51 E2 33 40 C3 F2-E4 90 48 CE 88 72 52 6A *..Q.3@....H..rRj* + 00000E20: FD F7 52 C3 A7 F3 A3 F2-BC 9F 60 49 BD 9A FA 77 *..R.......`I...w* + 00000E30: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 64 57 5B D9 *Y.2M.`(...xKdW[.* + 00000E40: 12 78 9A 2E 14 AD 56 F6-34 1F 52 AF 6B F8 0C F9 *.x....V.4.R.k...* + 00000E50: 44 00 78 59 75 E9 F0 4E-2D 64 D7 45 BD 9A FA 77 *D.xYu..N-d.E...w* + 00000E60: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 45 C7 C8 AE *Y.2M.`(...xKE...* + 00000E70: 75 0A CF BB 48 FC 37 52-7D 64 12 DD 64 4D AE D8 *u...H.7R}d..dM..* + 00000E80: 91 3C CD 8A 24 C9 4D 85-69 67 DF 8E *.<..$.M.ig..* +Variable RT+BS 'EFIGlobalVariable:VendorKeys' DataSize = 0x01 + 00000000: 01 *.* +Variable RT+BS 'EFIGlobalVariable:SignatureSupport' DataSize = 0x80 + 00000000: 92 A4 D2 3B C0 96 79 40-B4 20 FC F9 8E F1 03 ED *...;..y@. ......* + 00000010: 6E 87 76 70 C2 80 E6 4E-AA D2 28 B3 49 A6 86 5B *n.vp...N..(.I..[* + 00000020: 63 BF 6D 44 02 25 DA 4C-BC FA 24 65 D2 B0 FE 9D *c.mD.%.L..$e....* + 00000030: 26 16 C4 C1 4C 50 92 40-AC A9 41 F9 36 93 43 28 *&...LP.@..A.6.C(* + 00000040: A1 59 C0 A5 E4 94 A7 4A-87 B5 AB 15 5C 2B F0 72 *.Y.....J....\+.r* + 00000050: E8 66 57 3C 9C 26 34 4E-AA 14 ED 77 6E 85 B3 B6 *.fW<.&4N...wn...* + 00000060: 90 61 B3 E2 9B 87 3D 4A-AD 8D F2 E7 BB A3 27 84 *.a....=J......'.* + 00000070: 4F 44 F8 67 43 87 F1 48-A3 28 1E AA B8 73 60 80 *OD.gC..H.(...s`.* +Variable RT+BS 'EFIGlobalVariable:SecureBoot' DataSize = 0x01 + 00000000: 00 *.* +Variable RT+BS 'EFIGlobalVariable:SetupMode' DataSize = 0x01 + 00000000: 00 *.* +Variable RT+BS 'EFIGlobalVariable:DeployedMode' DataSize = 0x01 + 00000000: 00 *.* +Variable RT+BS 'EFIGlobalVariable:AuditMode' DataSize = 0x01 + 00000000: 00 *.* +Variable NV+RT+BS 'EFIGlobalVariable:PlatformLang' DataSize = 0x06 + 00000000: 65 6E 2D 55 53 00 *en-US.* +Variable NV+RT+BS 'EFIGlobalVariable:Boot0001' DataSize = 0xDA + 00000000: 01 00 00 00 76 00 55 00-45 00 46 00 49 00 3A 00 *....v.U.E.F.I.:.* + 00000010: 20 00 49 00 6E 00 74 00-65 00 6E 00 73 00 6F 00 * .I.n.t.e.n.s.o.* + 00000020: 20 00 52 00 61 00 69 00-6E 00 62 00 6F 00 77 00 * .R.a.i.n.b.o.w.* + 00000030: 20 00 4C 00 69 00 6E 00-65 00 20 00 38 00 2E 00 * .L.i.n.e. .8...* + 00000040: 30 00 37 00 2C 00 20 00-50 00 61 00 72 00 74 00 *0.7.,. .P.a.r.t.* + 00000050: 69 00 74 00 69 00 6F 00-6E 00 20 00 31 00 00 00 *i.t.i.o.n. .1...* + 00000060: 02 01 0C 00 D0 41 03 0A-00 00 00 00 01 01 06 00 *.....A..........* + 00000070: 00 15 03 05 06 00 00 00-03 05 06 00 01 00 04 01 *................* + 00000080: 2A 00 01 00 00 00 80 00-00 00 00 00 00 00 80 07 **...............* + 00000090: 78 00 00 00 00 00 6A C3-90 55 00 00 00 00 00 00 *x.....j..U......* + 000000A0: 00 00 00 00 00 00 01 01-7F FF 04 00 01 04 26 00 *..............&.* + 000000B0: EF 47 64 2D C9 3B A0 41-AC 19 4D 51 D0 1B 4C E6 *.Gd-.;.A..MQ..L.* + 000000C0: 35 00 37 00 32 00 38 00-46 00 31 00 38 00 43 00 *5.7.2.8.F.1.8.C.* + 000000D0: 00 00 7F FF 04 00 00 00-42 4F *........BO* +Variable NV+RT+BS 'EFIGlobalVariable:BootOrder' DataSize = 0x04 + 00000000: 01 00 00 00 *....* +Variable NV+RT+BS 'EFIGlobalVariable:Boot0000' DataSize = 0x12C + 00000000: 01 00 00 00 74 00 57 00-69 00 6E 00 64 00 6F 00 *....t.W.i.n.d.o.* + 00000010: 77 00 73 00 20 00 42 00-6F 00 6F 00 74 00 20 00 *w.s. .B.o.o.t. .* + 00000020: 4D 00 61 00 6E 00 61 00-67 00 65 00 72 00 00 00 *M.a.n.a.g.e.r...* + 00000030: 04 01 2A 00 02 00 00 00-00 18 0E 00 00 00 00 00 *..*.............* + 00000040: 00 20 03 00 00 00 00 00-7B D9 62 5D 9C EC 5D 49 *. ......{.b]..]I* + 00000050: B1 82 19 EC 1F BA 67 6D-02 02 04 04 46 00 5C 00 *......gm....F.\.* + 00000060: 45 00 46 00 49 00 5C 00-4D 00 49 00 43 00 52 00 *E.F.I.\.M.I.C.R.* + 00000070: 4F 00 53 00 4F 00 46 00-54 00 5C 00 42 00 4F 00 *O.S.O.F.T.\.B.O.* + 00000080: 4F 00 54 00 5C 00 42 00-4F 00 4F 00 54 00 4D 00 *O.T.\.B.O.O.T.M.* + 00000090: 47 00 46 00 57 00 2E 00-45 00 46 00 49 00 00 00 *G.F.W...E.F.I...* + 000000A0: 7F FF 04 00 57 49 4E 44-4F 57 53 00 01 00 00 00 *....WINDOWS.....* + 000000B0: 88 00 00 00 78 00 00 00-42 00 43 00 44 00 4F 00 *....x...B.C.D.O.* + 000000C0: 42 00 4A 00 45 00 43 00-54 00 3D 00 7B 00 39 00 *B.J.E.C.T.=.{.9.* + 000000D0: 64 00 65 00 61 00 38 00-36 00 32 00 63 00 2D 00 *d.e.a.8.6.2.c.-.* + 000000E0: 35 00 63 00 64 00 64 00-2D 00 34 00 65 00 37 00 *5.c.d.d.-.4.e.7.* + 000000F0: 30 00 2D 00 61 00 63 00-63 00 31 00 2D 00 66 00 *0.-.a.c.c.1.-.f.* + 00000100: 33 00 32 00 62 00 33 00-34 00 34 00 64 00 34 00 *3.2.b.3.4.4.d.4.* + 00000110: 37 00 39 00 35 00 7D 00-00 00 64 00 01 00 00 00 *7.9.5.}...d.....* + 00000120: 10 00 00 00 04 00 00 00-7F FF 04 00 *............* +Variable NV+RT+BS 'EFIGlobalVariable:Timeout' DataSize = 0x02 + 00000000: 02 00 *..* +Variable NV+RT+BS+AT 'EFIGlobalVariable:PK' DataSize = 0x36D + 00000000: A1 59 C0 A5 E4 94 A7 4A-87 B5 AB 15 5C 2B F0 72 *.Y.....J....\+.r* + 00000010: 6D 03 00 00 00 00 00 00-51 03 00 00 91 30 05 3B *m.......Q....0.;* + 00000020: 9F 6C CC 04 B1 AC E2 A5-1E 3B E5 F5 30 82 03 3D *.l.......;..0..=* + 00000030: 30 82 02 25 A0 03 02 01-02 02 10 CA CB DC 6C D4 *0..%..........l.* + 00000040: 53 C2 A2 49 47 46 4D 40-DC 6A DB 30 0D 06 09 2A *S..IGFM@.j.0...** + 00000050: 86 48 86 F7 0D 01 01 0B-05 00 30 2A 31 28 30 26 *.H........0*1(0&* + 00000060: 06 03 55 04 03 13 1F 41-53 55 53 54 65 4B 20 4E *..U....ASUSTeK N* + 00000070: 6F 74 65 62 6F 6F 6B 20-50 4B 20 43 65 72 74 69 *otebook PK Certi* + 00000080: 66 69 63 61 74 65 30 1E-17 0D 31 31 31 32 32 37 *ficate0...111227* + 00000090: 30 30 31 38 32 30 5A 17-0D 33 31 31 32 32 37 30 *001820Z..3112270* + 000000A0: 30 31 38 31 39 5A 30 2A-31 28 30 26 06 03 55 04 *01819Z0*1(0&..U.* + 000000B0: 03 13 1F 41 53 55 53 54-65 4B 20 4E 6F 74 65 62 *...ASUSTeK Noteb* + 000000C0: 6F 6F 6B 20 50 4B 20 43-65 72 74 69 66 69 63 61 *ook PK Certifica* + 000000D0: 74 65 30 82 01 22 30 0D-06 09 2A 86 48 86 F7 0D *te0.."0...*.H...* + 000000E0: 01 01 01 05 00 03 82 01-0F 00 30 82 01 0A 02 82 *..........0.....* + 000000F0: 01 01 00 83 F0 C9 66 5B-42 A1 F4 BE 4F 20 39 4A *......f[B...O 9J* + 00000100: 0C 99 21 61 64 64 03 14-2E 2B 28 08 8C BC D5 0B *..!add...+(.....* + 00000110: 4B 35 7A E4 90 CA 3C C7-F6 E9 E6 63 A8 F1 F9 FF *K5z...<....c....* + 00000120: 95 2C 86 92 ED 09 D8 30-D0 6B 7F 75 10 50 F1 E5 *.,.....0.k.u.P..* + 00000130: D2 17 EA DF 9F F5 F3 B8-D9 D9 84 C6 82 34 01 73 *.............4.s* + 00000140: AD A5 60 10 61 D9 20 33-F7 BC BA 1C 60 7D 64 FB *..`.a. 3....`}d.* + 00000150: CF 4C 2E 0E 0C B8 77 68-4A 53 73 C2 40 5C 89 C4 *.L....whJSs.@\..* + 00000160: 67 1B 46 E6 62 3C 3C DE-2F 85 76 56 24 03 E3 AB *g.F.b<<./.vV$...* + 00000170: 1F A1 21 6E 91 3B 30 AA-F2 CB FE 9E E4 E9 AF CC *..!n.;0.........* + 00000180: 29 BE BF F8 91 E8 58 64-6D FA 00 E6 02 C6 04 27 *).....Xdm......'* + 00000190: 6D F4 97 A7 BA FC 8B DC-F0 7C BB 60 5C B0 F7 0E *m........|.`\...* + 000001A0: 31 21 06 DD 80 B4 4B 2B-B2 AB 7A A4 F6 66 A1 CE *1!....K+..z..f..* + 000001B0: AB D8 87 82 4E F5 B0 98-14 E9 81 E7 09 6A 8A C6 *....N........j..* + 000001C0: 5C 2F D1 1D 14 2A F3 A7-59 09 89 B1 24 98 70 23 *\/...*..Y...$.p#* + 000001D0: C7 88 2B 05 E8 F7 DC 25-ED 15 72 1A 8E 4F 17 A5 *..+....%..r..O..* + 000001E0: 3A AE FF E1 BC 40 C2 EF-D1 C9 F0 4D 34 93 D2 32 *:....@.....M4..2* + 000001F0: F5 65 0F 02 03 01 00 01-A3 5F 30 5D 30 5B 06 03 *.e......._0]0[..* + 00000200: 55 1D 01 04 54 30 52 80-10 19 4E 3A 42 02 27 5A *U...T0R...N:B.'Z* + 00000210: 5A 6B A9 78 98 CA 7B D7-39 A1 2C 30 2A 31 28 30 *Zk.x..{.9.,0*1(0* + 00000220: 26 06 03 55 04 03 13 1F-41 53 55 53 54 65 4B 20 *&..U....ASUSTeK * + 00000230: 4E 6F 74 65 62 6F 6F 6B-20 50 4B 20 43 65 72 74 *Notebook PK Cert* + 00000240: 69 66 69 63 61 74 65 82-10 CA CB DC 6C D4 53 C2 *ificate.....l.S.* + 00000250: A2 49 47 46 4D 40 DC 6A-DB 30 0D 06 09 2A 86 48 *.IGFM@.j.0...*.H* + 00000260: 86 F7 0D 01 01 0B 05 00-03 82 01 01 00 43 E3 BB *.............C..* + 00000270: 15 68 CC 4E B3 45 DD 6A-F5 E5 67 5E 5B D4 4F C7 *.h.N.E.j..g^[.O.* + 00000280: 0D A2 83 E4 04 7C 0E 8A-85 78 BB 30 F1 4A 9A A0 *.....|...x.0.J..* + 00000290: BF 99 96 3F F5 8C 00 73-51 E6 BC 43 24 52 59 A3 *...?...sQ..C$RY.* + 000002A0: 56 ED 75 B5 05 5A EC 8B-63 25 F2 53 2D 9C 40 8A *V.u..Z..c%.S-.@.* + 000002B0: 24 C3 56 26 BC D2 B3 07-F9 C5 38 8A 61 67 CD 32 *$.V&......8.ag.2* + 000002C0: 3F 4C 9A 3F 2A 3C CB 33-0D 34 4E 67 7B DE B6 B7 *?L.?*<.3.4Ng{...* + 000002D0: BE D9 FA ED 53 5F 70 24-8E 3C 5A 71 C5 0D 65 11 *....S_p$.V\-'.&* + 000002C0: C7 DB 49 18 58 7A C8 AB-90 29 15 73 6A FD E4 4F *..I.Xz...).sj..O* + 000002D0: 0B EC AC A5 83 20 0F CE-B8 85 82 B4 B9 52 12 5C *..... .......R.\* + 000002E0: 6D A2 22 62 E7 4A EC AD-40 F3 B0 4E 19 A0 C7 9F *m."b.J..@..N....* + 000002F0: 13 37 9B 2D A1 58 A6 18-0E 24 B7 0B 79 8D E4 1F *.7.-.X...$..y...* + 00000300: 84 6F 19 97 52 C9 65 7A-0F 4E 14 F3 79 EE 2A 30 *.o..R.ez.N..y.*0* + 00000310: 7A 35 77 02 9D DB FA 9F-55 CF 13 AF 70 C3 8B 16 *z5w.....U...p...* + 00000320: B6 7A 11 E2 D3 86 DD E7-DD C4 E2 A9 F9 F5 96 8B *.z..............* + 00000330: BE 17 8C 42 7F 46 03 6B-B4 CC BD D4 A4 39 AC A7 *...B.F.k.....9..* + 00000340: DD 42 3E 95 3C 01 08 1D-D9 EE 7B 1C E3 FF 7C 56 *.B>.<.....{...|V* + 00000350: 50 7C 31 33 7E F3 EE C5-66 A6 17 E3 1D D6 9D D8 *P|13~...f.......* + 00000360: 18 5B 7B E2 ED 97 5D D7-C2 63 1D 49 CB BD 5F D7 *.[{...]..c.I.._.* + 00000370: A1 59 C0 A5 E4 94 A7 4A-87 B5 AB 15 5C 2B F0 72 *.Y.....J....\+.r* + 00000380: 18 06 00 00 00 00 00 00-FC 05 00 00 BD 9A FA 77 *...............w* + 00000390: 59 03 32 4D BD 60 28 F4-E7 8F 78 4B 30 82 05 E8 *Y.2M.`(...xK0...* + 000003A0: 30 82 03 D0 A0 03 02 01-02 02 0A 61 0A D1 88 00 *0..........a....* + 000003B0: 00 00 00 00 03 30 0D 06-09 2A 86 48 86 F7 0D 01 *.....0...*.H....* + 000003C0: 01 0B 05 00 30 81 91 31-0B 30 09 06 03 55 04 06 *....0..1.0...U..* + 000003D0: 13 02 55 53 31 13 30 11-06 03 55 04 08 13 0A 57 *..US1.0...U....W* + 000003E0: 61 73 68 69 6E 67 74 6F-6E 31 10 30 0E 06 03 55 *ashington1.0...U* + 000003F0: 04 07 13 07 52 65 64 6D-6F 6E 64 31 1E 30 1C 06 *....Redmond1.0..* + 00000400: 03 55 04 0A 13 15 4D 69-63 72 6F 73 6F 66 74 20 *.U....Microsoft * + 00000410: 43 6F 72 70 6F 72 61 74-69 6F 6E 31 3B 30 39 06 *Corporation1;09.* + 00000420: 03 55 04 03 13 32 4D 69-63 72 6F 73 6F 66 74 20 *.U...2Microsoft * + 00000430: 43 6F 72 70 6F 72 61 74-69 6F 6E 20 54 68 69 72 *Corporation Thir* + 00000440: 64 20 50 61 72 74 79 20-4D 61 72 6B 65 74 70 6C *d Party Marketpl* + 00000450: 61 63 65 20 52 6F 6F 74-30 1E 17 0D 31 31 30 36 *ace Root0...1106* + 00000460: 32 34 32 30 34 31 32 39-5A 17 0D 32 36 30 36 32 *24204129Z..26062* + 00000470: 34 32 30 35 31 32 39 5A-30 81 80 31 0B 30 09 06 *4205129Z0..1.0..* + 00000480: 03 55 04 06 13 02 55 53-31 13 30 11 06 03 55 04 *.U....US1.0...U.* + 00000490: 08 13 0A 57 61 73 68 69-6E 67 74 6F 6E 31 10 30 *...Washington1.0* + 000004A0: 0E 06 03 55 04 07 13 07-52 65 64 6D 6F 6E 64 31 *...U....Redmond1* + 000004B0: 1E 30 1C 06 03 55 04 0A-13 15 4D 69 63 72 6F 73 *.0...U....Micros* + 000004C0: 6F 66 74 20 43 6F 72 70-6F 72 61 74 69 6F 6E 31 *oft Corporation1* + 000004D0: 2A 30 28 06 03 55 04 03-13 21 4D 69 63 72 6F 73 **0(..U...!Micros* + 000004E0: 6F 66 74 20 43 6F 72 70-6F 72 61 74 69 6F 6E 20 *oft Corporation * + 000004F0: 4B 45 4B 20 43 41 20 32-30 31 31 30 82 01 22 30 *KEK CA 20110.."0* + 00000500: 0D 06 09 2A 86 48 86 F7-0D 01 01 01 05 00 03 82 *...*.H..........* + 00000510: 01 0F 00 30 82 01 0A 02-82 01 01 00 C4 E8 B5 8A *...0............* + 00000520: BF AD 57 26 B0 26 C3 EA-E7 FB 57 7A 44 02 5D 07 *..W&.&....WzD.].* + 00000530: 0D DA 4A E5 74 2A E6 B0-0F EC 6D EB EC 7F B9 E3 *..J.t*....m.....* + 00000540: 5A 63 32 7C 11 17 4F 0E-E3 0B A7 38 15 93 8E C6 *Zc2|..O....8....* + 00000550: F5 E0 84 B1 9A 9B 2C E7-F5 B7 91 D6 09 E1 E2 C0 *......,.........* + 00000560: 04 A8 AC 30 1C DF 48 F3-06 50 9A 64 A7 51 7F C8 *...0..H..P.d.Q..* + 00000570: 85 4F 8F 20 86 CE FE 2F-E1 9F FF 82 C0 ED E9 CD *.O. .../........* + 00000580: CE F4 53 6A 62 3A 0B 43-B9 E2 25 FD FE 05 F9 D4 *..Sjb:.C..%.....* + 00000590: C4 14 AB 11 E2 23 89 8D-70 B7 A4 1D 4D EC AE E5 *.....#..p...M...* + 000005A0: 9C FA 16 C2 D7 C1 CB D4-E8 C4 2F E5 99 EE 24 8B *........../...$.* + 000005B0: 03 EC 8D F2 8B EA C3 4A-FB 43 11 12 0B 7E B5 47 *.......J.C...~.G* + 000005C0: 92 6C DC E6 04 89 EB F5-33 04 EB 10 01 2A 71 E5 *.l......3....*q.* + 000005D0: F9 83 13 3C FF 25 09 2F-68 76 46 FF BA 4F BE DC *...<.%./hvF..O..* + 000005E0: AD 71 2A 58 AA FB 0E D2-79 3D E4 9B 65 3B CC 29 *.q*X....y=..e;.)* + 000005F0: 2A 9F FC 72 59 A2 EB AE-92 EF F6 35 13 80 C6 02 **..rY......5....* + 00000600: EC E4 5F CC 9D 76 CD EF-63 92 C1 AF 79 40 84 79 *.._..v..c...y@.y* + 00000610: 87 7F E3 52 A8 E8 9D 7B-07 69 8F 15 02 03 01 00 *...R...{.i......* + 00000620: 01 A3 82 01 4F 30 82 01-4B 30 10 06 09 2B 06 01 *....O0..K0...+..* + 00000630: 04 01 82 37 15 01 04 03-02 01 00 30 1D 06 03 55 *...7.......0...U* + 00000640: 1D 0E 04 16 04 14 62 FC-43 CD A0 3E A4 CB 67 12 *......b.C..>..g.* + 00000650: D2 5B D9 55 AC 7B CC B6-8A 5F 30 19 06 09 2B 06 *.[.U.{..._0...+.* + 00000660: 01 04 01 82 37 14 02 04-0C 1E 0A 00 53 00 75 00 *....7.......S.u.* + 00000670: 62 00 43 00 41 30 0B 06-03 55 1D 0F 04 04 03 02 *b.C.A0...U......* + 00000680: 01 86 30 0F 06 03 55 1D-13 01 01 FF 04 05 30 03 *..0...U.......0.* + 00000690: 01 01 FF 30 1F 06 03 55-1D 23 04 18 30 16 80 14 *...0...U.#..0...* + 000006A0: 45 66 52 43 E1 7E 58 11-BF D6 4E 9E 23 55 08 3B *EfRC.~X...N.#U.;* + 000006B0: 3A 22 6A A8 30 5C 06 03-55 1D 1F 04 55 30 53 30 *:"j.0\..U...U0S0* + 000006C0: 51 A0 4F A0 4D 86 4B 68-74 74 70 3A 2F 2F 63 72 *Q.O.M.Khttp://cr* + 000006D0: 6C 2E 6D 69 63 72 6F 73-6F 66 74 2E 63 6F 6D 2F *l.microsoft.com/* + 000006E0: 70 6B 69 2F 63 72 6C 2F-70 72 6F 64 75 63 74 73 *pki/crl/products* + 000006F0: 2F 4D 69 63 43 6F 72 54-68 69 50 61 72 4D 61 72 */MicCorThiParMar* + 00000700: 52 6F 6F 5F 32 30 31 30-2D 31 30 2D 30 35 2E 63 *Roo_2010-10-05.c* + 00000710: 72 6C 30 60 06 08 2B 06-01 05 05 07 01 01 04 54 *rl0`..+........T* + 00000720: 30 52 30 50 06 08 2B 06-01 05 05 07 30 02 86 44 *0R0P..+.....0..D* + 00000730: 68 74 74 70 3A 2F 2F 77-77 77 2E 6D 69 63 72 6F *http://www.micro* + 00000740: 73 6F 66 74 2E 63 6F 6D-2F 70 6B 69 2F 63 65 72 *soft.com/pki/cer* + 00000750: 74 73 2F 4D 69 63 43 6F-72 54 68 69 50 61 72 4D *ts/MicCorThiParM* + 00000760: 61 72 52 6F 6F 5F 32 30-31 30 2D 31 30 2D 30 35 *arRoo_2010-10-05* + 00000770: 2E 63 72 74 30 0D 06 09-2A 86 48 86 F7 0D 01 01 *.crt0...*.H.....* + 00000780: 0B 05 00 03 82 02 01 00-D4 84 88 F5 14 94 18 02 *................* + 00000790: CA 2A 3C FB 2A 92 1C 0C-D7 A0 D1 F1 E8 52 66 A8 *.*<.*........Rf.* + 000007A0: EE A2 B5 75 7A 90 00 AA-2D A4 76 5A EA 79 B7 B9 *...uz...-.vZ.y..* + 000007B0: 37 6A 51 7B 10 64 F6 E1-64 F2 02 67 BE F7 A8 1B *7jQ{.d..d..g....* + 000007C0: 78 BD BA CE 88 58 64 0C-D6 57 C8 19 A3 5F 05 D6 *x....Xd..W..._..* + 000007D0: DB C6 D0 69 CE 48 4B 32-B7 EB 5D D2 30 F5 C0 F5 *...i.HK2..].0...* + 000007E0: B8 BA 78 07 A3 2B FE 9B-DB 34 56 84 EC 82 CA AE *..x..+...4V.....* + 000007F0: 41 25 70 9C 6B E9 FE 90-0F D7 96 1F E5 E7 94 1F *A%p.k...........* + 00000800: B2 2A 0C 8D 4B FF 28 29-10 7B F7 D7 7C A5 D1 76 *.*..K.().{..|..v* + 00000810: B9 05 C8 79 ED 0F 90 92-9C C2 FE DF 6F 7E 6C 0F *...y........o~l.* + 00000820: 7B D4 C1 45 DD 34 51 96-39 0F E5 5E 56 D8 18 05 *{..E.4Q.9..^V...* + 00000830: 96 F4 07 A6 42 B3 A0 77-FD 08 19 F2 71 56 CC 9F *....B..w....qV..* + 00000840: 86 23 A4 87 CB A6 FD 58-7E D4 69 67 15 91 7E 81 *.#.....X~.ig..~.* + 00000850: F2 7F 13 E5 0D 8B 8A 3C-87 84 EB E3 CE BD 43 E5 *.......<......C.* + 00000860: AD 2D 84 93 8E 6A 2B 5A-7C 44 FA 52 AA 81 C8 2D *.-...j+Z|D.R...-* + 00000870: 1C BB E0 52 DF 00 11 F8-9A 3D C1 60 B0 E1 33 B5 *...R.....=.`..3.* + 00000880: A3 88 D1 65 19 0A 1A E7-AC 7C A4 C1 82 87 4E 38 *...e.....|....N8* + 00000890: B1 2F 0D C5 14 87 6F FD-8D 2E BC 39 B6 E7 E6 C3 *./....o....9....* + 000008A0: E0 E4 CD 27 84 EF 94 42-EF 29 8B 90 46 41 3B 81 *...'...B.)..FA;.* + 000008B0: 1B 67 D8 F9 43 59 65 CB-0D BC FD 00 92 4F F4 75 *.g..CYe......O.u* + 000008C0: 3B A7 A9 24 FC 50 41 40-79 E0 2D 4F 0A 6A 27 76 *;..$.PA@y.-O.j'v* + 000008D0: 6E 52 ED 96 69 7B AF 0F-F7 87 05 D0 45 C2 AD 53 *nR..i{......E..S* + 000008E0: 14 81 1F FB 30 04 AA 37-36 61 DA 4A 69 1B 34 D8 *....0..76a.Ji.4.* + 000008F0: 68 ED D6 02 CF 6C 94 0C-D3 CF 6C 22 79 AD B1 F0 *h....l....l"y...* + 00000900: BC 03 A2 46 60 A9 C4 07-C2 21 82 F1 FD F2 E8 79 *...F`....!.....y* + 00000910: 32 60 BF D8 AC A5 22 14-4B CA C1 D8 4B EB 7D 3F *2`....".K...K.}?* + 00000920: 57 35 B2 E6 4F 75 B4 B0-60 03 22 53 AE 91 79 1D *W5..Ou..`."S..y.* + 00000930: D6 9B 41 1F 15 86 54 70-B2 DE 0D 35 0F 7C B0 34 *..A...Tp...5.|.4* + 00000940: 72 BA 97 60 3B F0 79 EB-A2 B2 1C 5D A2 16 B8 87 *r..`;.y....]....* + 00000950: C5 E9 1B F6 B5 97 25 6F-38 9F E3 91 FA 8A 79 98 *......%o8.....y.* + 00000960: C3 69 0E B7 A3 1C 20 05-97 F8 CA 14 AE 00 D7 C4 *.i.... .........* + 00000970: F3 C0 14 10 75 6B 34 A0-1B B5 99 60 F3 5C B0 C5 *....uk4....`.\..* + 00000980: 57 4E 36 D2 32 84 BF 9E-A1 59 C0 A5 E4 94 A7 4A *WN6.2....Y.....J* + 00000990: 87 B5 AB 15 5C 2B F0 72-64 04 00 00 00 00 00 00 *....\+.rd.......* + 000009A0: 48 04 00 00 E4 0A C4 6D-E8 2E 4C 9C A3 14 0F C7 *H......m..L.....* + 000009B0: B2 00 87 10 30 82 04 34-30 82 03 1C A0 03 02 01 *....0..40.......* + 000009C0: 02 02 09 00 B9 41 24 A0-18 2C 92 67 30 0D 06 09 *.....A$..,.g0...* + 000009D0: 2A 86 48 86 F7 0D 01 01-0B 05 00 30 81 84 31 0B **.H........0..1.* + 000009E0: 30 09 06 03 55 04 06 13-02 47 42 31 14 30 12 06 *0...U....GB1.0..* + 000009F0: 03 55 04 08 0C 0B 49 73-6C 65 20 6F 66 20 4D 61 *.U....Isle of Ma* + 00000A00: 6E 31 10 30 0E 06 03 55-04 07 0C 07 44 6F 75 67 *n1.0...U....Doug* + 00000A10: 6C 61 73 31 17 30 15 06-03 55 04 0A 0C 0E 43 61 *las1.0...U....Ca* + 00000A20: 6E 6F 6E 69 63 61 6C 20-4C 74 64 2E 31 34 30 32 *nonical Ltd.1402* + 00000A30: 06 03 55 04 03 0C 2B 43-61 6E 6F 6E 69 63 61 6C *..U...+Canonical* + 00000A40: 20 4C 74 64 2E 20 4D 61-73 74 65 72 20 43 65 72 * Ltd. Master Cer* + 00000A50: 74 69 66 69 63 61 74 65-20 41 75 74 68 6F 72 69 *tificate Authori* + 00000A60: 74 79 30 1E 17 0D 31 32-30 34 31 32 31 31 31 32 *ty0...1204121112* + 00000A70: 35 31 5A 17 0D 34 32 30-34 31 31 31 31 31 32 35 *51Z..42041111125* + 00000A80: 31 5A 30 81 84 31 0B 30-09 06 03 55 04 06 13 02 *1Z0..1.0...U....* + 00000A90: 47 42 31 14 30 12 06 03-55 04 08 0C 0B 49 73 6C *GB1.0...U....Isl* + 00000AA0: 65 20 6F 66 20 4D 61 6E-31 10 30 0E 06 03 55 04 *e of Man1.0...U.* + 00000AB0: 07 0C 07 44 6F 75 67 6C-61 73 31 17 30 15 06 03 *...Douglas1.0...* + 00000AC0: 55 04 0A 0C 0E 43 61 6E-6F 6E 69 63 61 6C 20 4C *U....Canonical L* + 00000AD0: 74 64 2E 31 34 30 32 06-03 55 04 03 0C 2B 43 61 *td.1402..U...+Ca* + 00000AE0: 6E 6F 6E 69 63 61 6C 20-4C 74 64 2E 20 4D 61 73 *nonical Ltd. Mas* + 00000AF0: 74 65 72 20 43 65 72 74-69 66 69 63 61 74 65 20 *ter Certificate * + 00000B00: 41 75 74 68 6F 72 69 74-79 30 82 01 22 30 0D 06 *Authority0.."0..* + 00000B10: 09 2A 86 48 86 F7 0D 01-01 01 05 00 03 82 01 0F *.*.H............* + 00000B20: 00 30 82 01 0A 02 82 01-01 00 BF 5B 3A 16 74 EE *.0.........[:.t.* + 00000B30: 21 5D AE 61 ED 9D 56 AC-BD DE DE 72 F3 DD 7E 2D *!].a..V....r..~-* + 00000B40: 4C 62 0F AC C0 6D 48 08-11 CF 8D 8B FB 61 1F 27 *Lb...mH......a.'* + 00000B50: CC 11 6E D9 55 3D 39 54-EB 40 3B B1 BB E2 85 34 *..n.U=9T.@;....4* + 00000B60: 79 CA F7 7B BF BA 7A C8-10 2D 19 7D AD 59 CF A6 *y..{..z..-.}.Y..* + 00000B70: D4 E9 4E 0F DA AE 52 EA-4C 9E 90 CE C6 99 0D 4E *..N...R.L......N* + 00000B80: 67 65 78 5D F9 D1 D5 38-4A 4A 7A 8F 93 9C 7F 1A *gex]...8JJz.....* + 00000B90: A3 85 DB CE FA 8B F7 C2-A2 21 2D 9B 54 41 35 10 *.........!-.TA5.* + 00000BA0: 57 13 8D 6C BC 29 06 50-4A 7E EA 99 A9 68 A7 3B *W..l.).PJ~...h.;* + 00000BB0: C7 07 1B 32 9E A0 19 87-0E 79 BB 68 99 2D 7E 93 *...2.....y.h.-~.* + 00000BC0: 52 E5 F6 EB C9 9B F9 2B-ED B8 68 49 BC D9 95 50 *R......+..hI...P* + 00000BD0: 40 5B C5 B2 71 AA EB 5C-57 DE 71 F9 40 0A DD 5B *@[..q..\W.q.@..[* + 00000BE0: AC 1E 84 2D 50 1A 52 D6-E1 F3 6B 6E 90 64 4F 5B *...-P.R...kn.dO[* + 00000BF0: B4 EB 20 E4 61 10 DA 5A-F0 EA E4 42 D7 01 C4 FE *.. .a..Z...B....* + 00000C00: 21 1F D9 B9 C0 54 95 42-81 52 72 1F 49 64 7A C8 *!....T.B.Rr.Idz.* + 00000C10: 6C 24 F1 08 70 0B 4D A5-A0 32 D1 A0 1C 57 A8 4D *l$..p.M..2...W.M* + 00000C20: E3 AF A5 8E 05 05 3E 10-43 A1 02 03 01 00 01 A3 *......>.C.......* + 00000C30: 81 A6 30 81 A3 30 1D 06-03 55 1D 0E 04 16 04 14 *..0..0...U......* + 00000C40: AD 91 99 0B C2 2A B1 F5-17 04 8C 23 B6 65 5A 26 *.....*.....#.eZ&* + 00000C50: 8E 34 5A 63 30 1F 06 03-55 1D 23 04 18 30 16 80 *.4Zc0...U.#..0..* + 00000C60: 14 AD 91 99 0B C2 2A B1-F5 17 04 8C 23 B6 65 5A *......*.....#.eZ* + 00000C70: 26 8E 34 5A 63 30 0F 06-03 55 1D 13 01 01 FF 04 *&.4Zc0...U......* + 00000C80: 05 30 03 01 01 FF 30 0B-06 03 55 1D 0F 04 04 03 *.0....0...U.....* + 00000C90: 02 01 86 30 43 06 03 55-1D 1F 04 3C 30 3A 30 38 *...0C..U...<0:08* + 00000CA0: A0 36 A0 34 86 32 68 74-74 70 3A 2F 2F 77 77 77 *.6.4.2http://www* + 00000CB0: 2E 63 61 6E 6F 6E 69 63-61 6C 2E 63 6F 6D 2F 73 *.canonical.com/s* + 00000CC0: 65 63 75 72 65 2D 62 6F-6F 74 2D 6D 61 73 74 65 *ecure-boot-maste* + 00000CD0: 72 2D 63 61 2E 63 72 6C-30 0D 06 09 2A 86 48 86 *r-ca.crl0...*.H.* + 00000CE0: F7 0D 01 01 0B 05 00 03-82 01 01 00 3F 7D F6 76 *............?}.v* + 00000CF0: A5 B3 83 B4 2B 7A D0 6D-52 1A 03 83 C4 12 A7 50 *....+z.mR......P* + 00000D00: 9C 47 92 CC C0 94 77 82-D2 AE 57 B3 99 04 F5 32 *.G....w...W....2* + 00000D10: 3A C6 55 1D 07 DB 12 A9-56 FA D8 D4 76 20 EB E4 *:.U.....V...v ..* + 00000D20: C3 51 DB 9A 5C 9C 92 3F-18 73 DA 94 6A A1 99 38 *.Q..\..?.s..j..8* + 00000D30: 8C A4 88 6D C1 FC 39 71-D0 74 76 16 03 3E 56 23 *...m..9q.tv..>V#* + 00000D40: 35 D5 55 47 5B 1A 1D 41-C2 D3 12 4C DC FF AE 0A *5.UG[..A...L....* + 00000D50: 92 9C 62 0A 17 01 9C 73-E0 5E B1 FD BC D6 B5 19 *..b....s.^......* + 00000D60: 11 7A 7E CD 3E 03 7E 66-DB 5B A8 C9 39 48 51 FF *.z~.>.~f.[..9HQ.* + 00000D70: 53 E1 9C 31 53 91 1B 3B-10 75 03 17 BA E6 81 02 *S..1S..;.u......* + 00000D80: 80 94 70 4C 46 B7 94 B0-3D 15 CD 1F 8E 02 E0 68 *..pLF...=......h* + 00000D90: 02 8F FB F9 47 1D 7D A2-01 C6 07 51 C4 9A CC ED *....G.}....Q....* + 00000DA0: DD CF A3 5D ED 92 BB BE-D1 FD E6 EC 1F 33 51 73 *...].........3Qs* + 00000DB0: 04 BE 3C 72 B0 7D 08 F8-01 FF 98 7D CB 9C E0 69 *...........f..m* + 00000DE0: BD B8 27 77 C1 42 94 BD-FC 6A 0A BC *..'w.B...j..* +Variable NV+RT+BS 'EFIGlobalVariable:ErrOut' DataSize = 0x1E + 00000000: 02 01 0C 00 D0 41 03 0A-00 00 00 00 01 01 06 00 *.....A..........* + 00000010: 00 02 02 03 08 00 00 14-01 80 7F FF 04 00 *..............* +Variable NV+RT+BS 'EFIGlobalVariable:ConIn' DataSize = 0x44 + 00000000: 02 01 0C 00 D0 41 03 0A-00 00 00 00 01 01 06 00 *.....A..........* + 00000010: 00 1F 02 01 0C 00 D0 41-03 03 00 00 00 00 7F 01 *.......A........* + 00000020: 04 00 02 01 0C 00 D0 41-03 0A 00 00 00 00 01 01 *.......A........* + 00000030: 06 00 00 15 03 05 06 00-00 00 03 05 06 00 00 00 *................* + 00000040: 7F FF 04 00 *....* +Variable NV+RT+BS 'EFIGlobalVariable:ConOut' DataSize = 0x1E + 00000000: 02 01 0C 00 D0 41 03 0A-00 00 00 00 01 01 06 00 *.....A..........* + 00000010: 00 02 02 03 08 00 00 14-01 80 7F FF 04 00 *..............* diff --git a/blogs/2021-11-28/VS2022CLI.png b/blogs/2021-11-28/VS2022CLI.png new file mode 100644 index 00000000000..9cd33ebeadb Binary files /dev/null and b/blogs/2021-11-28/VS2022CLI.png differ diff --git a/blogs/2021-11-28/_cdeStr2Argcv.c b/blogs/2021-11-28/_cdeStr2Argcv.c new file mode 100644 index 00000000000..bb03eb606c6 --- /dev/null +++ b/blogs/2021-11-28/_cdeStr2Argcv.c @@ -0,0 +1,161 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + _cdeStr2Argcv.c + +Abstract: + + CDE internal convert a string to argc/argv equivalent + +Author: + + Kilian Kegel + +--*/ + +#include + +/** _cdeStr2Argcv() + +Synopsis + + int _cdeStr2Argcv(char **argv,char *szCmdline); + +Description + + split up a string in a argc/argv equivalent. + +Returns + + @param[in] char **argv + @param[in] char szCmdLine + + @retval argc + +**/ +int _cdeStr2Argcv(char** argv, char* szCmdline) { + + int fBStore = 0/*blank store vs. copy*/; + int fSStore = 1/*separator store*/; +#define ISBLANK(x) (0x20 == x || '\t' == x) +#define ISSLASH(x) ('\\' == x) +#define ISQUOTE(x) ('"' == x) +#define DELIM 1 + int nSlashBack = 0; + char* pSrc = szCmdline, * pDst = &pSrc[-1]; + int argc = 0; + enum STATE { + PROCESS_BEGIN,/*eat leading blanks...*/ + PROCESS_BLANKS/*skip or store blanks*/, + PROCESS_NONBLANKS, + PROCESS_SLASHBACK, + PROCESS_EVEN_SLASHBACK_QUOTATION, + PROCESS_ODD_SLASHBACK_QUOTATION, + PROCESS_DELIMITER, + PROCESS_SLASHBACKSTORAGE, + PROCESS_QUOTATION + }state = PROCESS_BLANKS, old; + + while (*pSrc || state == PROCESS_SLASHBACKSTORAGE || + state == PROCESS_ODD_SLASHBACK_QUOTATION || + state == PROCESS_EVEN_SLASHBACK_QUOTATION || + state == PROCESS_SLASHBACK) + { + old = state; + switch (state) { + + case PROCESS_BEGIN: + if (!ISBLANK(*pSrc)) + state = PROCESS_NONBLANKS; + break; + + case PROCESS_BLANKS: + if (ISBLANK(*pSrc)) { + if (fBStore) + *++pDst = *pSrc; + else + if (fSStore) + fSStore = 0, + * ++pDst = DELIM; + } + else + fSStore = 1, + state = PROCESS_NONBLANKS; + break; + + case PROCESS_NONBLANKS: + + state = ISSLASH(*pSrc) ? PROCESS_SLASHBACK : state; + state = ISQUOTE(*pSrc) ? PROCESS_QUOTATION : state; + state = ISBLANK(*pSrc) ? PROCESS_BLANKS : state; + + if (state != PROCESS_NONBLANKS) + break; + *++pDst = *pSrc; + break; + + case PROCESS_SLASHBACK: + + if (ISSLASH(*pSrc)) { + nSlashBack++; + break; + } + + if (ISQUOTE(*pSrc)) { + state = nSlashBack % 2 ? PROCESS_ODD_SLASHBACK_QUOTATION : PROCESS_EVEN_SLASHBACK_QUOTATION; + nSlashBack /= 2; + pSrc++; + } + else + state = PROCESS_SLASHBACKSTORAGE; + + break; + + case PROCESS_QUOTATION: + fBStore = !fBStore; + state = PROCESS_BLANKS; + //hack for "" at end of string + if(0 == fBStore && '\0' == pSrc[1]) + *++pDst = DELIM; + break; + + case PROCESS_SLASHBACKSTORAGE: + case PROCESS_ODD_SLASHBACK_QUOTATION: + case PROCESS_EVEN_SLASHBACK_QUOTATION: + while (nSlashBack--) + *++pDst = '\\'; + if (state == PROCESS_ODD_SLASHBACK_QUOTATION) + *++pDst = '"'; + if (state != PROCESS_SLASHBACKSTORAGE) + fBStore = state == PROCESS_EVEN_SLASHBACK_QUOTATION ? !fBStore : fBStore; + nSlashBack = 0; + state = PROCESS_BLANKS; + break; + } + + if (old == state || (old == PROCESS_QUOTATION && state == PROCESS_BLANKS)) + pSrc++; + }//while(*pSrc) + + if (*pDst != DELIM || fBStore) + *++pDst = DELIM; + *++pDst = '\0'; + + for (argc = 0, pSrc = szCmdline; *pSrc != '\0' && argc < (CDE_ARGV_MAX - 1); argc++) { + argv[argc] = pSrc; + while (*pSrc++ != DELIM) + ; + pSrc[-1] = '\0'; + } + + argv[argc] = NULL; + + return argc; +} diff --git a/blogs/2021-11-28/fgets.c b/blogs/2021-11-28/fgets.c new file mode 100644 index 00000000000..6b216a0b507 --- /dev/null +++ b/blogs/2021-11-28/fgets.c @@ -0,0 +1,72 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + Fgets.c + +Abstract: + + Implementation of the Standard C function. + Get a string from a stream. + +Author: + + Kilian Kegel + +--*/ +#include + +/** fgets +Synopsis + #include + char *fgets(char * restrict s, int n,FILE * restrict stream); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fgets-fgetws?view=msvc-160&viewFallbackFrom=vs-2019 + The fgets function reads at most one less than the number of characters specified by + n from the stream pointed to by stream into the array pointed to by s. + No additional characters are read after a new-line character (which is retained) + or after end-of-file. A null character is written immediately after the last character + read into the array. +Returns + The fgets function returns s if successful. If end-of-file is encountered and no + characters have been read into the array, the contents of the array remain unchanged and a + null pointer is returned. If a read error occurs during the operation, the array contents are + indeterminate and a null pointer is returned. + + @param[in] char * s + @param[in] int n + @param[in] FILE *stream + + @retval char * s on success + + @retval NULL on error. + +**/ +char* fgets(char* s, int n, FILE* stream) { + + char c; + int i; + + do { + + for (i = 0, c = 0; i < (n - 1) && c != '\n'; i++) { + + if (1 != fread(&c, 1, 1, stream)) + break; + + s[i] = c; + } + + if (i != 0) + s[i] = '\0'; + + } while (0); + + return i == 0 ? NULL : s; +} \ No newline at end of file diff --git a/blogs/2021-11-28/find.c b/blogs/2021-11-28/find.c new file mode 100644 index 00000000000..d2e23afcbf9 --- /dev/null +++ b/blogs/2021-11-28/find.c @@ -0,0 +1,232 @@ +// +// MSDOS/Windows FIND command for UEFI Shell +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// + +#include +#include +#include +#include +#include + +#define ELC(x) ( sizeof(x) / sizeof(x[0]) ) /* element count */ +#define MAXSLASHPARM 7 +#define MAXLINELEN 10 * 1024 + +int parm[MAXSLASHPARM] = { 0 }; + +int IsSlashParm(int iargv) { + + return (parm[0] == iargv || parm[1] == iargv || parm[2] == iargv || parm[3] == iargv || parm[4] == iargv || parm[5] == iargv || parm[6] == iargv); + +} + +int IsFile(char** argv, int iargv) { + int nRet = 0; + + do { + if (1 == IsSlashParm(iargv)) + break; //break with nRet == 1 -> is '/C' or '/N' or ... + if (0 == strncmp("/", argv[iargv], strlen("/"))) { + nRet = -1; + break; + } + nRet = 1; + } while (0); + + return nRet; +} + +int main(int argc, char** argv) { + int i, iargv = 2; + FILE* fp = stdin; // take file from STDIN, by default + enum PARM { V, C, N, I, O/*FF*/, L/*OFFLINE*/, H }; + int nRet = 1; // assume NOT FOUND + int cntFile = 0; + size_t linelen, stringlen; + char* pLineOrg = malloc(MAXLINELEN), * pLineUpcase = malloc(MAXLINELEN) , * pString; + int line,count; + char fUTF16 = 0; + + do { + // + // get parameters from command line + // + if (argc > 1) { + stringlen = strlen(argv[1]); // first argument IS! THE! searchstring. (the ""magic stuff can not be implemented in Standard C) + pString = malloc(1 + stringlen); + strcpy(pString, argv[1]); + } + else { + fprintf(stderr, "FIND: Parameter format not correct\n"); + exit(3); + break;//while(0) + } + + // + // check all commandline parameters + // + for (i = 1; i < argc; i++) { + + //parm[H] = (0 == strcmp("/h", argv[i])) ? i : parm[H]; // stricmp() is not part of Standard C !!! + //parm[H] = (0 == strcmp("/H", argv[i])) ? i : parm[H]; // stricmp() is not part of Standard C !!! + parm[H] = (0 == strcmp("/?", argv[i])) ? i : parm[H]; // stricmp() is not part of Standard C !!! + parm[V] = (0 == strcmp("/v", argv[i])) ? i : parm[V]; // stricmp() is not part of Standard C !!! + parm[V] = (0 == strcmp("/V", argv[i])) ? i : parm[V]; // stricmp() is not part of Standard C !!! + parm[C] = (0 == strcmp("/c", argv[i])) ? i : parm[C]; // stricmp() is not part of Standard C !!! + parm[C] = (0 == strcmp("/C", argv[i])) ? i : parm[C]; // stricmp() is not part of Standard C !!! + parm[N] = (0 == strcmp("/n", argv[i])) ? i : parm[N]; // stricmp() is not part of Standard C !!! + parm[N] = (0 == strcmp("/N", argv[i])) ? i : parm[N]; // stricmp() is not part of Standard C !!! + parm[I] = (0 == strcmp("/i", argv[i])) ? i : parm[I]; // stricmp() is not part of Standard C !!! + parm[I] = (0 == strcmp("/I", argv[i])) ? i : parm[I]; // stricmp() is not part of Standard C !!! + //parm[O] = (0 == strcmp("/OFF", argv[i])) ? i : parm[O]; + //parm[L] = (0 == strcmp("/OFFLINE", argv[i])) ? i : parm[L]; + } + // + // print help screen and exit + // + if (parm[H]) { + printf("Searches for a text string in a file or files or in STDIN\n\n"); + printf("FIND \"string\" [/V][/C][/N][/I] [[drive:][path]filename[...]]\n\n"); + printf(" \"string\" Specifies the text string to find. It must be the first parameter\n"); + printf(" /V or /v Displays all lines NOT containing the specified string.\n"); + printf(" /C or /c Displays only the count of lines containing the string.\n"); + printf(" /N or /n Displays line numbers with the displayed lines.\n"); + printf(" /I or /i Ignores the case of characters when searching for the string.\n"); + printf(" [drive:][path] filename\n"); + printf(" Specifies a file or files to search.\n"); + printf("\nIf a path is not specified, FIND searches the text typed at the prompt\n"); + printf(" or piped from another command.\n"); + exit(0); + } + //printf("parmV = %d, parmC = %d, parmN = %d, parmI = %d, parmO = %d, parmL = %d\n", parm[V], parm[C], parm[N], parm[I], parm[O], parm[L]); + + for (i = 2; i < argc; i++) { + int xRet = IsFile(argv, i); + + if (-1 == xRet) { + fprintf(stderr, "FIND: Invalid switch \"%s\"\n",argv[i]); + exit(3); + } + + cntFile += (1 == xRet ? 1 : 0); // count number of files passed in the command line + } + + //printf("cntFile: %d\n", cntFile); // debug + if (0 != parm[I]) // case independance upcase + for (i = 0; i < stringlen; i++) + pString[i] = (char)toupper(pString[i]); + + do { + // + // check, if filename is passed in the commandline. If not, read from file instead from STDIN + // + if (0 < cntFile ) { // take filename from commandline + if (!IsFile(argv, iargv)) + continue; + if (NULL == (fp = fopen(argv[iargv], "r"))) { + fprintf(stderr, "File not found - %s\n", argv[iargv]); // file is not present... + exit(1); + } + else { + printf("\n---------- %s%s", argv[iargv], 0 == parm[C] ? "\n" : ": "); + + // + // check BOM byte order mark UTF-16 (LE) https://en.wikipedia.org/wiki/Byte_order_mark#UTF-16 + // + if (1) { + size_t fsize; + + fseek(fp, 0, SEEK_END); + fsize = ftell(fp); + rewind(fp); + + if (2 <= fsize) + { + unsigned short BOM; + + fread(&BOM, 2, 1, fp); + + fUTF16 = (0xFEFF == BOM); + + if(0 == fUTF16) + rewind(fp); + + } + } + } + } + + line = 0; + count = 0; + + memset(pLineOrg, 0, MAXLINELEN); + while (NULL != fgets(pLineOrg, MAXLINELEN, fp)) + { + int equality = (0 == parm[V]) || (0 == stringlen && 0 != parm[V]) ; + int match; + line++; + + // + // convert wide character string (wcs) to string (str) + // + if (1 == fUTF16) { + int x = 0; + char c; + + //don't work for LINUX: + // + // wcstombs(pLineOrg, (wchar_t*)pLineOrg, MAXLINELEN); + // + // wchar_t size in Linux i 4, in Windows 2: + // http://www.firstobject.com/wchar_t-string-on-linux-osx-windows.htm + + while ( + c = pLineOrg[x * sizeof(short)], + pLineOrg[x * sizeof(char)] = c, + x++, + c != '\0' + ); + fgetc(fp); // adjust file index to next UTF16-LE character, + // get high-part of UTF16-LE from '\n' + } + + linelen = strlen(pLineOrg); + + for (i = 0; i < linelen; i++) + if (0 != parm[I]) // case independance upcase + pLineUpcase[i] = (char)toupper(pLineOrg[i]); + else + pLineUpcase[i] = pLineOrg[i]; + + + for (i = 0, match = 0; i + stringlen <= linelen; i++) + { + match = ((0 == stringlen && 0 != parm[V]) || (0 == strncmp(&pLineUpcase[i], pString, stringlen))); + if (match) + break;//for + } + if (match == equality) { + count++; + if (0 == parm[C]) { + + if (0 != parm[N]) // printf line number + printf("[%d]", line); + printf("%s", pLineOrg); + nRet = 0; + } + } + memset(pLineOrg, 0, (linelen + 1) * sizeof(wchar_t)); // clear old buffer before reading next line + } + if (0 != parm[C]) + printf("%d\n", count); + + if (stdin != fp) + fclose(fp); // close fp, that was opened above + } while (++iargv < argc ); // next file... + } while (0); + return nRet; +} + diff --git a/blogs/2021-11-28/lib b/blogs/2021-11-28/lib new file mode 160000 index 00000000000..277b10bee5b --- /dev/null +++ b/blogs/2021-11-28/lib @@ -0,0 +1 @@ +Subproject commit 277b10bee5b68e1d0ea58e6cc1b6d025df93cd56 diff --git a/blogs/2021-11-28/more.c b/blogs/2021-11-28/more.c new file mode 100644 index 00000000000..5274a8ee209 --- /dev/null +++ b/blogs/2021-11-28/more.c @@ -0,0 +1,95 @@ +// +// MSDOS/Windows/UNIX MORE command for UEFI Shell +// +// Copyright(c) 2017 - 2021, Kilian Kegel.All rights reserved. +// SPDX - License - Identifier: BSD-2-Clause-Patent +// + +#include +#include +#include +#undef NULL +#include + +#define ELC(x) ( sizeof(x) / sizeof(x[0]) ) // element count + +int main(int argc, char** argv) { + EFI_SYSTEM_TABLE* pEfiSystemTable = (void*)(argv[-1]); // pEfiSystemTable is passed in argv[-1] + EFI_HANDLE* hEfiImageHandle = (void*)(argv[-2]); // ImageHandle is passed in argv[-2] + UINTN Cols, Rows, Line = 0; // + int c, i, n = 1, idiv = 1; // + char* pBuf, * p; // + FILE* fp = stdin; // take file from STDIN, by default + char fUTF16 = 0; // flag file format + int nRet = EXIT_SUCCESS; + + pEfiSystemTable->ConOut->QueryMode( // get number of text lines of the screen + pEfiSystemTable->ConOut, + (UINTN)pEfiSystemTable->ConOut->Mode->Mode, + &Cols, &Rows + ); + + do { + // + // check, if filename is passed in the commandline. If so, read from file instead from STDIN + // + if (argc > 1) { // take filename from commandline + if (NULL == (fp = fopen(argv[n], "r"))) { // open filename from commandline + fprintf(stderr, "Cannot access file %s\n", argv[n]);// file is not present... + nRet = EXIT_FAILURE; // set exit code + break; // ...exit program + } else { // detect file format + // + // check BOM byte order mark UTF-16 (LE) https://en.wikipedia.org/wiki/Byte_order_mark#UTF-16 + // + unsigned short BOM = 0; + fread(&BOM, 2, 1, fp); + fUTF16 = (0xFEFF == BOM); + if (0 == fUTF16) + rewind(fp); + } + } + + // + // read from file/STDIN until EOF to continously enlarged buffer + // + idiv = fUTF16 ? 2 : 1; // adjust idiv to decide skip zero high byte + pBuf = NULL; // inital request for realloc() + for (i = 0 ; EOF != (c = fgetc(fp)); i++) { // read character from file/STDIN until EOF + if(fUTF16) // fif UTF16 file format... + if (0 != (i % 2)) // ... if zero high byte... + continue; // ... skip that byte and continue + pBuf = realloc(pBuf, i / idiv + 1); // allocate buffer / increase buffersize + if (NULL == pBuf) // check allocation failure... + abort(); // ...abort(), if so + pBuf[i / idiv] = (char)c; // store character in memory buffer + } // + pBuf[i / idiv] = '\0'; // set string termination + + // + // Buffer contains the entire file now. Print file line-wise to the screen and stop after # rows and wait for key + // + for (Line = 0, p = strtok(pBuf, "\n"); p != NULL; Line++) // display the text screen wise + { + if (Rows == 1 + Line) { + UINTN Index; + EFI_INPUT_KEY Key; + EFI_STATUS Status; + printf("-- More --"); + do { // read real kbhit(), since STDIN is redirected + pEfiSystemTable->BootServices->WaitForEvent(1, pEfiSystemTable->ConIn->WaitForKey, &Index); + Status = pEfiSystemTable->ConIn->ReadKeyStroke(pEfiSystemTable->ConIn, &Key); + } while (EFI_SUCCESS != Status); + printf("\n"); + Line = 0; + } + printf("%s\n", p); // print the text line + p = strtok(NULL, "\n"); // get the next text line + } + if(stdin != fp) + fclose(fp); // close fp, that was opened above + } while (++n < argc); // next file... + + return nRet; +} + diff --git a/blogs/2021-11-28/osifUefiShellFileRead.c b/blogs/2021-11-28/osifUefiShellFileRead.c new file mode 100644 index 00000000000..7fa418390a0 --- /dev/null +++ b/blogs/2021-11-28/osifUefiShellFileRead.c @@ -0,0 +1,155 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + _osifUefiShellFileRead.c + +Abstract: + + OS interface (osif) read file UEFI Shell + +Author: + + Kilian Kegel + +--*/ +#pragma warning (disable:4189/*local variable is initialized but not referenced*/) +#define OS_EFI +#include +#include +#include +#include + +/** +Synopsis + #include + size_t _osifUefiShellFileRead(IN CDE_APP_IF* pCdeAppIf, void* ptr, size_t nelem, CDEFILE* pCdeFile) +Description + Read a file +Paramters + IN CDE_APP_IF* pCdeAppIf : application interface + void* ptr : buffer + size_t nelem : number of bytes + CDEFILE* pCdeFile : CDEFILE* file handle +Returns + CDEFILE*: success + NULL : failure +**/ +size_t _osifUefiShellFileRead(IN CDE_APP_IF* pCdeAppIf, void* ptr, size_t nelem, CDEFILE* pCdeFile) +{ + size_t BufferSize = nelem; + char* pBuffer = ptr; + wchar_t* pwcBuffer = ptr; + wchar_t BOM = 0xFEFF; + unsigned int i = 0; + EFI_STATUS Status = EFI_SUCCESS; +#define OPENMODE pCdeFile->openmode + + do { + + if (OPENMODE & O_CDESTDIN) + { + static wchar_t wcbuffer[BUFSIZ];/* BUFSIZ can not be changed on STDIN */ + + if (0 == (OPENMODE & O_CDEREDIR)) + {// keyboard is connected directly, BOM is NOT transmitted, terminated by users's ENTER, but this ENTER is not transmitted + + BufferSize = (nelem - 2/*reserve space for CRLF */) * 2; + + Status = __cdeOnErrSet_status(pCdeFile->pRootProtocol->Read(pCdeFile->pFileProtocol, &BufferSize, &wcbuffer[0])); + + if (EFI_SUCCESS != Status) + break; + + for (i = 0; i < BufferSize / 2; i++) + pBuffer[i] = (char)wcbuffer[i]; + + pBuffer[i + 0] = '\r'; + pBuffer[i + 1] = '\n'; + + BufferSize = BufferSize / 2 + 2/* CRLF */; + } + else + {// STDIN is redirected, BOM IS transmitted, terminated by EOF + + if (0 == (OPENMODE & O_CDEDETECTED)) + { + size_t BufferSizeBOM = 2; + // + // read first TWO bytes and detect if it is BOM == 0xFEFF, if yes 16bit input, otherwise ASCII + // + wcbuffer[0] = 0; + Status = __cdeOnErrSet_status(pCdeFile->pRootProtocol->Read(pCdeFile->pFileProtocol, &BufferSizeBOM, pwcBuffer/* == pBuffer */)); + if (EFI_SUCCESS != Status) + break; + + if (pwcBuffer[0] == BOM)/* == pBuffer[0..1] */ + { + OPENMODE |= O_CDEDETECTED + O_CDEWIDTH16; + + BufferSize = nelem * 2; + Status = __cdeOnErrSet_status(pCdeFile->pRootProtocol->Read(pCdeFile->pFileProtocol, &BufferSize, &wcbuffer[0])); + + if (EFI_SUCCESS != Status) + break; + + for (i = 0; i < BufferSize / 2; i++) + pBuffer[i] = (char)wcbuffer[i]; + + BufferSize = BufferSize / 2; + } + else { + + OPENMODE |= O_CDEDETECTED; + + BufferSize = nelem - 2/* two bytes already read */; + Status = __cdeOnErrSet_status(pCdeFile->pRootProtocol->Read(pCdeFile->pFileProtocol, &BufferSize, &pBuffer[2/* two bytes already read */])); + + if (EFI_SUCCESS != Status) + break; + BufferSize += 2;/* two bytes already read */; + } + } + else { + if (O_CDEWIDTH16 == (OPENMODE & O_CDEWIDTH16)) { + BufferSize = nelem * 2; + Status = __cdeOnErrSet_status(pCdeFile->pRootProtocol->Read(pCdeFile->pFileProtocol, &BufferSize, &wcbuffer[0])); + + if (EFI_SUCCESS != Status) + break; + + for (i = 0; i < BufferSize / 2; i++) + pBuffer[i] = (char)wcbuffer[i]; + + BufferSize = BufferSize / 2; + + } + else { + BufferSize = nelem; + Status = __cdeOnErrSet_status(pCdeFile->pRootProtocol->Read(pCdeFile->pFileProtocol, &BufferSize, &pBuffer[0])); + + if (EFI_SUCCESS != Status) + break; + } + + } + } + } + else { + + Status = __cdeOnErrSet_status(pCdeFile->pRootProtocol->Read(pCdeFile->pFileProtocol, &BufferSize, ptr)); + + if (EFI_SUCCESS != Status) { + break; + } + } + + } while (0); + return EFI_SUCCESS == Status ? (size_t)BufferSize : 0; +} diff --git a/blogs/2021-11-28/ucs2utf16.png b/blogs/2021-11-28/ucs2utf16.png new file mode 100644 index 00000000000..65ada3d383f Binary files /dev/null and b/blogs/2021-11-28/ucs2utf16.png differ diff --git a/blogs/2021-12-19/CdeLoadOptions.h.diff.png b/blogs/2021-12-19/CdeLoadOptions.h.diff.png new file mode 100644 index 00000000000..9df67fff6d9 Binary files /dev/null and b/blogs/2021-12-19/CdeLoadOptions.h.diff.png differ diff --git a/blogs/2021-12-19/LoadOption.c b/blogs/2021-12-19/LoadOption.c new file mode 100644 index 00000000000..535396af803 --- /dev/null +++ b/blogs/2021-12-19/LoadOption.c @@ -0,0 +1,355 @@ +/*! +@copyright + Copyright (c) 2021, Kilian Kegel. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +@file main.c + +@brief CdeLoadOption UEFI shell tool to add, modify, disable and delete command line options for CdePkg based POST driver\n + +@details @brief CdeLoadOption tool to add, modify, disable and delete command line options for CdePkg based POST driver\n + +@todo + +@mainpage + CdeLoadOption driver for MinnowBoard + +@section intro_sec Introduction +For demonstration purpose only the MemoryInit.efi driver depex' on\n + CDE_PEI_TMPTEST0_GUID {0xCDE00055, 0xb0ff, 0x498b, { 0xb1, 0x7c, 0xed, 0xb3, 0xa0, 0x2e, 0x7f, 0x6e }}\n + that is installed by this driver.\n + ATTENTION: CdeLoadOption has to be the last driver in the list to be started as Cde-PRE-memory driver in the related flash file descriptor .FDF file\n + The .FDF file is located here: overrides\edk2-platforms\PlatformPkg.fdf\n + +@subsection Parm_sec Command line parameters + 1. CdeLoadOption [/?] [/h] [/help] + +*/ +#include +#include +#include +#include +#undef NULL +#include + +extern char* _strefierror(EFI_STATUS errcode); // Toro C extention according to strerror() + +#define BSIZE 4096 + +typedef struct _NVRAMCOMMANDLINE { + int rejectStart; // 1 -> suppress start of driver, even if registered with EFI_CALLER_ID_GUID. 0 -> start driver and pass command line to it + char CommandLine[0]; /* assigned command line includeing filename*/ +}NVRAMCOMMANDLINE; + +int main(int argc, char** argv) { + + size_t len = argc > 2 ? 1 + strlen(argv[2]) : 0; + EFI_SYSTEM_TABLE* SystemTable = (EFI_SYSTEM_TABLE*)(argv[-1]); //SystemTable is passed in argv[-1] +// EFI_HANDLE ImageHandle = (void*)(argv[-2]); //ImageHandle is passed in argv[-2] + EFI_STATUS Status = EFI_SUCCESS; + EFI_GUID guid; + UINT32 Attributes = EFI_VARIABLE_NON_VOLATILE + EFI_VARIABLE_BOOTSERVICE_ACCESS + EFI_VARIABLE_RUNTIME_ACCESS, * pAttributes = &Attributes; + UINTN datasize = BSIZE; + NVRAMCOMMANDLINE* pNvram = malloc(BSIZE); + NVRAMCOMMANDLINE* pBuf = malloc(sizeof(NVRAMCOMMANDLINE) + len); + int n, i; + int nRet = 1; + int icmd = 0, idis = 0, idel = 0, iena = 0, iguid = 0, ilst = 0, ihlp = 0; + + do { + + // + // check command line parameters + // + for (i = 1; i < argc; i++) { + if (0 == strcmp("/cmd", argv[i])) + icmd = i; + if (0 == strcmp("/dis", argv[i])) + idis = i; + if (0 == strcmp("/ena", argv[i])) + iena = i; + if (0 == strcmp("/del", argv[i])) + idel = i; + if (0 == strcmp("/guid", argv[i])) + iguid = i; + if (0 == strcmp("/list", argv[i])) + ilst = i; + if ((0 == strcmp("/?", argv[i])) || (0 == strcmp("/h", argv[i])) || (0 == strcmp("/help", argv[i]))) + ihlp = i; + } + + if (ihlp || 1 == argc) { + printf("\nLoadOption UEFI shell tool to add, modify, disable and delete command line\noptions for CdePkg based POST drivers\n\n"); + printf("CdeLoadOption /guid 12345678-0000-1111-2233-445566778899 [/cmd \"commandline\"] [/dis] [/ena] [/del]\n"); + printf(" or\nLoadOption /list\n\n"); + printf(" /list list all command line reserved for CdePkg drivers\n"); + printf(" /guid FILE_GUID of the POST driver\n"); + printf(" /cmd command line including of program name and parameters\n"); + printf(" /dis disable a driver during POST. The main() function is not invoked\n"); + printf(" /ena enable a driver for POST.\n"); + printf(" /del delete command line for a driver. The driver is invoked during POST as an \"unknownCdeDriver\"\n"); + break; + } + + if (0 != ilst) { + char fPrint = 0; + wchar_t* pVarName = malloc(BSIZE); + size_t VarNameSize = BSIZE; + int num = 0, found = 0; + + memset(&guid, 0, sizeof(guid)); + + wcscpy(pVarName, L""); + do { + + + VarNameSize = BSIZE; + + Status = SystemTable->RuntimeServices->GetNextVariableName( + &VarNameSize, + pVarName, + &guid + ); + + if ((Status == EFI_NOT_FOUND)) { + if (0 == found) { + printf("No \"CdeLoadOption\" variable found in NVRAM\n"); + } + break; + } + + if ((Status != EFI_SUCCESS)) { + fprintf(stdout, __FILE__"(%d): ""num %d -> %s\n", __LINE__, num, _strefierror(Status)); + break; + } + + num++; + + //if (len) { + fPrint = !wcscmp(pVarName, L"CdeLoadOption"); + found = found + fPrint; + // //printf(__FILE__"(%d): ""%S vs. %S, len == %d, fPrint == %d\n", __LINE__, pVarName2, pVarName, len, fPrint); + //} + //else { + // fPrint = 1; + //} + + if (Status == EFI_SUCCESS && fPrint == 1) { + pVarName[VarNameSize] = '\0'; + printf("%S : ", pVarName); + printf("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X ->", + guid.Data1, + guid.Data2, + guid.Data3, + guid.Data4[0], + guid.Data4[1], + guid.Data4[2], + guid.Data4[3], + guid.Data4[4], + guid.Data4[5], + guid.Data4[6], + guid.Data4[7]); + + datasize = BSIZE; + Status = SystemTable->RuntimeServices->GetVariable( + L"CdeLoadOption" /* IN CHAR16 * VariableName */, + &guid /* IN EFI_GUID * VendorGuid */, + NULL /* OUT UINT32 * Attributes OPTIONAL*/, + &datasize /* IN OUT UINTN * DataSize */, + pNvram /* OUT VOID * Data OPTIONAL*/ + ); + + //fprintf(stdout, __FILE__"%d): ""%s\n", __LINE__, _strefierror(Status)); + + if (EFI_SUCCESS == Status) { + printf("\"%s\" %s\n", pNvram->CommandLine, pNvram->rejectStart ? "Start rejected" : ""); + } + + } + } while (Status == EFI_SUCCESS); + + if (num == 0) { + fprintf(stdout, __FILE__"(%d): ""\"CdeLoadOption\" NVRAM variable not found\n", __LINE__); + } + break; + } + // + // check command line parameters + // + if (0 == iguid) { + fprintf(stdout, "MISSING parameter: /guid 12345678-AAAA-BBBB-CCDD-112233445566\n"); + break; + } + + if (0 == icmd && 0 == idis && 0 == idel && 0 == iena) { + fprintf(stdout, "MISSING parameter: /cmd \"drivername parm1 parm2\"\n"); + fprintf(stdout, " /dis\n"); + fprintf(stdout, " /ena\n"); + fprintf(stdout, " /del\n"); + break; + } + + memset(&guid, 0, sizeof(guid)); + + // + // get and test the guid passed after /guid command line parameter + // + n = sscanf(argv[iguid + 1], "%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx", + &guid.Data1, + &guid.Data2, + &guid.Data3, + &guid.Data4[0], + &guid.Data4[1], + &guid.Data4[2], + &guid.Data4[3], + &guid.Data4[4], + &guid.Data4[5], + &guid.Data4[6], + &guid.Data4[7]); + if (11 != n) { + fprintf(stdout, "Invalid GUID format\nUse: 11111111-2222-3333-4455-66778899AABB\n"); + break; + } + + // + // /del - delete NVRAM variable + // + if (idel) { + Status = SystemTable->RuntimeServices->SetVariable( + L"CdeLoadOption", + &guid, + EFI_VARIABLE_NON_VOLATILE + EFI_VARIABLE_BOOTSERVICE_ACCESS + EFI_VARIABLE_RUNTIME_ACCESS, + 0, + NULL + ); + + if (Status != EFI_SUCCESS) + fprintf(stdout, __FILE__"(%d): ""%s\n", __LINE__, _strefierror(Status)); + break; + } + + // + // /dis - disable (set rejectStart flag) + // + if (idis) { + + datasize = BSIZE; + pNvram = realloc(pNvram, BSIZE); + + Status = SystemTable->RuntimeServices->GetVariable( + L"CdeLoadOption" /* IN CHAR16 * VariableName */, + &guid /* IN EFI_GUID * VendorGuid */, + pAttributes /* OUT UINT32 * Attributes OPTIONAL*/, + &datasize /* IN OUT UINTN * DataSize */, + pNvram /* OUT VOID * Data OPTIONAL*/ + ); + + if (Status != EFI_SUCCESS) { + fprintf(stdout, __FILE__"(%d): ""%s\n", __LINE__, _strefierror(Status)); + break; + } + + pNvram->rejectStart = 1; // set disable flag + + Status = SystemTable->RuntimeServices->SetVariable( + L"CdeLoadOption" /* IN CHAR16* VariableName */, + &guid /* IN EFI_GUID* VendorGuid */, + *pAttributes /* IN UINT32 Attributes */, + datasize /* IN UINTN DataSize */, + pNvram /* IN VOID* Data */ + ); + if (Status != EFI_SUCCESS) { + fprintf(stdout, __FILE__"(%d): ""%s\n", __LINE__, _strefierror(Status)); + break; + } + printf("LoadOption : %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X successfully DISABLED\n", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + break; + + } + + // + // /ena - enable (clear rejectStart flag) + // + if (iena) { + + datasize = BSIZE; + pNvram = realloc(pNvram, BSIZE); + + Status = SystemTable->RuntimeServices->GetVariable( + L"CdeLoadOption" /* IN CHAR16 * VariableName */, + &guid /* IN EFI_GUID * VendorGuid */, + pAttributes /* OUT UINT32 * Attributes OPTIONAL*/, + &datasize /* IN OUT UINTN * DataSize */, + pNvram /* OUT VOID * Data OPTIONAL*/ + ); + + if (Status != EFI_SUCCESS) { + fprintf(stdout, __FILE__"(%d): ""%s\n", __LINE__, _strefierror(Status)); + break; + } + + pNvram->rejectStart = 0; // set disable flag + + Status = SystemTable->RuntimeServices->SetVariable( + L"CdeLoadOption" /* IN CHAR16* VariableName */, + &guid /* IN EFI_GUID* VendorGuid */, + *pAttributes /* IN UINT32 Attributes */, + datasize /* IN UINTN DataSize */, + pNvram /* IN VOID* Data */ + ); + + if (Status != EFI_SUCCESS) { + fprintf(stdout, __FILE__"(%d): ""%s\n", __LINE__, _strefierror(Status)); + break; + } + printf("LoadOption : %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X successfully ENABLED\n", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + break; + } + + // + // /cmd the command line passed to the driver "drivername parm1 parm2" + // + if (icmd) { + + pBuf->rejectStart = (0 != idis); + + strcpy(pBuf->CommandLine, argv[icmd + 1]); + + Status = SystemTable->RuntimeServices->SetVariable( + L"CdeLoadOption", + &guid, + EFI_VARIABLE_NON_VOLATILE + EFI_VARIABLE_BOOTSERVICE_ACCESS + EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(NVRAMCOMMANDLINE) + len, + pBuf + ); + + if (Status != EFI_SUCCESS) { + fprintf(stdout, __FILE__"(%d): ""%s\n", __LINE__, _strefierror(Status)); + break; + } + + datasize = BSIZE; + + Status = SystemTable->RuntimeServices->GetVariable( + L"CdeLoadOption" /* IN CHAR16 * VariableName */, + &guid /* IN EFI_GUID * VendorGuid */, + NULL /* OUT UINT32 * Attributes OPTIONAL*/, + &datasize /* IN OUT UINTN * DataSize */, + pNvram /* OUT VOID * Data OPTIONAL*/ + ); + + //fprintf(stdout, __FILE__"%d): ""%s\n", __LINE__, _strefierror(Status)); + + if (EFI_SUCCESS != Status) { + fprintf(stdout, __FILE__"(%d): ""fail to read NVRAM variable \"CdeLoadOption\" : %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X -> %s\n", __LINE__, guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7], _strefierror(Status)); + break; + } + printf("LoadOption : %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X command line \"%s\" successfully createdn\n", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7], pNvram->CommandLine); + + } + } while (0); + + return nRet; +} + + diff --git a/blogs/2021-12-19/README.md b/blogs/2021-12-19/README.md new file mode 100644 index 00000000000..9ca96a3eca1 --- /dev/null +++ b/blogs/2021-12-19/README.md @@ -0,0 +1,742 @@ +### CdePkgBlog 2021-12-19 +# Redfish on CdePkg +![redfish](https://redfish.dmtf.org/sites/default/files/DMTF_Redfish_logo_R.75.jpg) +### Table of content +* [Abstract](README.md#Abstract) +* [Introduction](README.md#Introduction) + * [introductory email](https://edk2.groups.io/g/devel/topic/cdepkgblog_2021_12_19/87843834?p=,,,20,0,0,0::recentpostdate/sticky,,,20,2,0,87843834,previd=1639947117658429604,nextid=1639753762684061333&previd=1639947117658429604&nextid=1639753762684061333) +* [In a nutshell: **CdePkg**](README.md#in-a-nutshell-cdepkg) + * [A short comparison with RedfishCrtLib](README.md#a-short-comparison-with-redfishcrtlib) + * [RedfishCrtLib conflicts with CdePkg by design](README.md#redfishcrtlib-conflicts-with-cdepkg-by-design) +* [Transformation of a traditional UEFI DXE driver to CdePkg driver](README.md#transformation-of-a-traditional-uefi-dxe-driver-to-cdepkg-driver) + * [Adjusting the .INF file to run CdePkg features](README.md#adjusting-the-inf-file-to-run-cdepkg-features) + * [Adjusting the ENTRY_POINT-.C file to run CdePkg features](README.md#adjusting-the-entry_point-c-file-to-run-cdepkg-features) + * [Adding a command line (EmulatorPkg)](README.md#adding-a-command-line-emulatorpkg) + * [Adding a command line on a real platform](README.md#adding-a-command-line-on-a-real-platform) +* [Perform Standard C in RestJsonStructureDxe.c in the Emulator](README.md#perform-standard-c-in-restjsonstructuredxec-in-the-emulator) + * [`wctype.h` demonstration](README.md#wctypeh-demonstration) + * [`wchar.h` demonstration](README.md#wcharh-demonstration) +* [CDETRACE() -- An introduction of a new DEBUG/TRACE concept for UEFI platforms](README.md#cdetrace----an-introduction-of-a-new-debugtrace-concept-for-uefi-platforms) + * [tianocore `DEBUG()`](README.md#cdetrace----an-introduction-of-a-new-debugtrace-concept-for-uefi-platforms) + * [`CDETRACE()`](README.md#cdetrace) +* [Coming up soon](README.md#coming-up-soon) + +## Abstract +Demonstration on how to transform existing UEFI POST drivers to run in a *hosted environment*, starting at +`int main(int argc, char **argv)` and taking arguments from an *emulated* or a NVRAM stored command line, +using the latest development environment from Microsoft and the *open source*, *monolithic*, *multi-target* +[**toro C Library**](https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library) + +NOTE: All statements regarding implementation specific details of **toro C Library** are always strictly focused on +my observations of Microsoft C Library, running "C" locale, at UTC timezone. Referring to Standard/ANSI C might be a +Microsoft specific implementation of the specification, but I always give my best to double-check the statements on GCC x64. In critical cases +also old Borland, Watcom and Digital Mars C compiler and library were queried. **toro C Library** is engineered -- not "scientifized". +This is also true for all upcoming CdePkgBlogs. + +## Introduction + +The transformation of current UEFI drivers, that run traditionally in a "limited" [*freestanding environment*](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=23) +to drivers running in a full blown [*hosted environment*](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=23) (that currently +provides a comprehensive -- but not yet full -- set of [Standard C functions](https://github.com/KilianKegel/toro-C-Library/blob/master/implemented.md)) is demonstrated along the [**RedfishPkg**](https://github.com/tianocore/edk2/tree/master/RedfishPkg#uefi-redfish-edk2-implementation). + +I call this execution environment "*limited freestanding environment*", because for C99-[`long long`]((http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=45))-data-type +integer shift and divided operators can not be used with the 32 bit codegenerator. E.g. a source code snippet like +```c + if(1) + { + volatile long long longlong = 3; + + while(longlong / 7); + } +``` + +will fail to link the driver with `error LNK2001: unresolved external symbol __alldiv` in the Microsoft tool chain.
+NOTE: In GNU tool chain it will fail for the very same reason with a similiar message. + +Once, the driver is transformed to be a **CdePkg**-based driver this type of error cannot appear anymore. + +NOTE: Currently **CdePkg** is only available for Microsoft tool chain. It is planned to provide the same functionality +for GNU and LLVM based tool chains, too. + +ATTENTION: DON'T TRY TO USE **toro C Library** and **CdeLib.lib** with the GNU linker! The GNU linker used to contain +bugs regarding MS-COFF .OBJ format and maybe there are still some more bugs beside those that were already found and solved: https://github.com/KilianKegel/GNU-ld-for-MicrosoftCOFF-to-LinuxELF#gnu-ld-for-microsoftcoff-to-linuxelf + +# In a nutshell: **CdePkg** +[**CdePkg**](https://github.com/KilianKegel/CdePkg#cdepkg) was introduced to ease porting +of Standard C source code to UEFI drivers and to overcome the "barrier" +in front of the open source **tianocore** project. + +The "barrier" of **tianocore** exists and is kept up by three reasons:
+1. introduction of unique data types +2. substitution of shift and divide operators for 64 bit integers +3. absence of any Standard C functions from [chapter 7](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=176) of the C specification [ISO/IEC 9899](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=1) + +Item (3) of the above list implies one positive argument: +Since none of the Standard C Library functions are provided by the native UEFI (Library) API at all, none of the Standard C functions +could be implemented faultily.
+ +The design rules below apply to **CdePkg**:
+1. reimplementing/cloning all C90/C95-related functions of the Microsoft C Library + * reimplementing exact behaviour (NOTE: original Microsoft C Library source code is *not* available to me -- this is a [clean room design](https://en.wikipedia.org/wiki/Clean_room_design)) +2. multi platform targets + * **CdePkg**/**toro C Library** based programs can be linked to run on Windows NT too. (Linux support is under construction) + * this *core feature* is the basis to compare behaviour against original Microsoft C Library +3. verified functionality of each [available function](https://github.com/KilianKegel/toro-C-Library/blob/master/implemented.md#validation-status), publishing [known bugs](https://github.com/KilianKegel/toro-C-Library#known-bugs) (e.g. missing floating point format specifiers) + * in principle: ***once a (faulty) API is published, application code relies on it and the API cannot be fixed anymore*** +4. space optimization + * each single function has its own C source file and gets its own .OBJ in the library and is pulled into the driver separately from any other function. Only `CRT0` modules were excluded from this concept, because `CRT0` modules are used to control the random .LIB/.OBJ link sequence in the UEFI build process. + * split architecture into worker driver (`CdeServices`) and wrapper functions (`CdeLib.lib`) for POST UEFI drivers to prevent from code space explosion + if `printf()`, `scanf()` and `malloc()` is duplicated in > 100 different drivers of a particular UEFI BIOS +5. introduction of *hosted environment* for POST drivers +6. introduction of an improved DEBUG-TRACE-capability, as a design concept: `CDETRACE(msg_cond)` + * enable format string and parameter validation by the compiler to prevent from [[1](https://bugzilla.tianocore.org/show_bug.cgi?id=3257)], [[2](https://bugzilla.tianocore.org/show_bug.cgi?id=3253)] and related bugs + * unlimited string length + * automatically include *ORIGIN* of the trace: module-, file-, function-name + line number into trace message (time stamp on demand) + * configurable *SEVERITY* string (`INFO`, `WARNING`, `ERROR`, `FATAL` ...) + * traces can be controlled *per driver* to prevent message overhead, speed up TRACE-POST + * using existing `DEBUG()` macros in **CdePkg**-enabled drivers + + +## A short comparison with **RedfishCrtLib** +On the one hand, a recent [**RedfishCrtLib.c**](https://github.com/tianocore/edk2/blob/master/RedfishPkg/PrivateLibrary/RedfishCrtLib/RedfishCrtLib.c) +and [**RedfishCrtLib.h**](https://github.com/tianocore/edk2/blob/master/RedfishPkg/Include/Library/RedfishCrtLib.h) +introduce a **short-term** approach. That was taken from `CryptoPkg` CrtLibSupport and is also used in `RegularExpressionDxe`and `BrotliDecompressLib`. + +[**RedfishCrtLib.h**](https://github.com/tianocore/edk2/blob/master/RedfishPkg/Include/Library/RedfishCrtLib.h#L529) +```c + . + . + . +#define snprintf(buf, len, ...) RedfishAsciiSPrint(buf,len,__VA_ARGS__) +#define vsnprintf(buf, len, format, marker) RedfishAsciiVSPrint((buf),(len),(format),(marker)) + . + . + . +``` +[`snprintf()`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=302) and +[`vsnprintf()`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=306) are specified by [ISO/IEC 9899](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=1). +It is not sufficent just to replace the `%s`to `%a`, the entire format specifiers have to be supported:
+(http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=287) + +[**`RedfishCrtLib.c`**](https://github.com/tianocore/edk2/blob/master/RedfishPkg/PrivateLibrary/RedfishCrtLib/RedfishCrtLib.c#L1014) +```c +/** + This is the Redfish version of CRT vsnprintf function, this function replaces "%s" to + "%a" before invoking AsciiVSPrint(). That is because "%s" is unicode base on edk2 + environment however "%s" is ascii code base on vsnprintf(). + See definitions of AsciiVSPrint() for the details. + . + . + . +**/ +``` + + +The content of the standard header files is not arbitrary! It is defined in the [ISO/IEC 9899](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=1) specification (here only C90/C95 header files listed) +and there is only a little margin to be "creative":
+* [`assert.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=261), read https://publications.gbdirect.co.uk/c_book/chapter9/diagnostics.html +* [`ctype.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=193), read https://publications.gbdirect.co.uk/c_book/chapter9/character_handling.html +* [`errno.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=198) +* [`float.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=209) +* [`limits.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=215), read https://publications.gbdirect.co.uk/c_book/chapter9/limits.html +* [`locale.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=216), read https://publications.gbdirect.co.uk/c_book/chapter9/localization.html +* [`math.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=224), read https://publications.gbdirect.co.uk/c_book/chapter9/maths_functions.html +* [`setjmp.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=255), read https://publications.gbdirect.co.uk/c_book/chapter9/nonlocal_jumps.html +* [`signal.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=258), read https://publications.gbdirect.co.uk/c_book/chapter9/signal_handling.html +* [`stdarg.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=261), read https://publications.gbdirect.co.uk/c_book/chapter9/stdarg.html +* [`stddef.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=266) +* [`stdint.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=267), C99 but nice to have +* [`stdio.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=274), read https://publications.gbdirect.co.uk/c_book/chapter9/input_and_output.html +* [`stdlib.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=318), read https://publications.gbdirect.co.uk/c_book/chapter9/general_utilities.html +* [`string.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=337), read https://publications.gbdirect.co.uk/c_book/chapter9/string_handling.html +* [`time.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=350), read https://publications.gbdirect.co.uk/c_book/chapter9/date_and_time.html +* [`wchar.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=360), C99 but strongly required for UEFI +* [`wctype.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=405), C99 but strongly required for UEFI + +#### NOTE: If it keeps true that the **RedfishCrtLib**-functions differ from specified Standard C functions and the header files are kept although holding the wrong content, the advantage of portability **turns into untrustworthiness**. In this case the smallest change in parameters or programflow always requires a full validation of the entire module. + +On the other hand, the **toro C Library**/**CdePkg** +* each single function's behaviour is tested painstakingly against its Microsoft C Library counterpart +* each single format specifier of the [`scanf()`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=294)- and [`print()`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=287)-family functions is validated meticulously + * NOTE: This does not guarantee it to be bug-free +* a true (partial) validation using [**SuperTest**](https://solidsands.com/products/supertest) is in preparation + +## **`RedfishCrtLib`** conflicts with **`CdePkg`** by design +The full **CdePkg**-function-set is only functional when **`RedfishCrtLib`** is NOT being used at all. +This is because the [**RedfishCrtLib.c**](https://github.com/tianocore/edk2/blob/master/RedfishPkg/PrivateLibrary/RedfishCrtLib/RedfishCrtLib.c) +implements all functions in one monolithic .C/.OBJ file. + +Doing so, it violates the ***one definition rule***. + +If during the link process *one* single function from `RedfishCrtLib` is invoked, (*e.g. a new function called [`isdchar()`](https://github.com/tianocore/edk2/blob/master/RedfishPkg/PrivateLibrary/RedfishCrtLib/RedfishCrtLib.c#L40) +that is yet unknown to any Standard/ANSI/POSIX-C specification but pretty much sounds like it belongs to the `ctype.h` functions and for that reason its existence and naming irritates*) +then at the same time all the other functions/symbols will be tried to be pulled in by the linker. If the linker has already found +a function/symbol with the same name in another .OBJ module, it conflicts with `RedfishCrtLib.obj` and will break the build. + + + RedfishCrtLib.lib(RedfishCrtLib.obj) : error LNK2005: _fprintf already defined in CdeLib.lib(Fprintf.obj) + RedfishCrtLib.lib(RedfishCrtLib.obj) : error LNK2005: _fwrite already defined in CdeLib.lib(Fwrite.obj) + RedfishCrtLib.lib(RedfishCrtLib.obj) : error LNK2005: _free already defined in CdeLib.lib(Free.obj) + RedfishCrtLib.lib(RedfishCrtLib.obj) : error LNK2005: _malloc already defined in CdeLib.lib(Malloc.obj) + RedfishCrtLib.lib(RedfishCrtLib.obj) : error LNK2005: _isalnum already defined in CdeLib.lib(isalnum.obj) + +The 29 symbols below were defined in the monolitic `RedfishCrtLib.lib`/`RedfishCrtLib.obj` "translation unit" and could not be handled +separately by LINK.EXE and will lead to LNK2005 https://docs.microsoft.com/en-us/cpp/error-messages/tool-errors/linker-tools-error-lnk2005?view=msvc-170: + + errno + errnum_message + _fltused + isalnum() + isdchar() + isspace() + malloc() + free() + strdup() + toupper() + Digit2Val() + strtoll() + strtol() + strtod () + strpbrk() + strerror() + calloc() + time() + qsort() + fgetc() + fopen() + fread() + fwrite() + fclose() + fprintf() + CheckFormatingString() + ReplaceUnicodeToAsciiStrFormat() + RedfishAsciiVSPrint() + RedfishAsciiSPrint() + +#### NOTE: **In a proper library design every single symbol should be placed in a dedicated "translation unit"/.OBJ module. The library manager creates a .LIB/library from one or more of those *single-symbol*-.OBJ files. Then the linker can pick each symbol independently from remaining library content.** + +#### NOTE: **THIS IS A VERY COMMON DESIGN FLAW IN THE UEFI ENVIRONMENT AND THE ROOT CAUSE FOR LOTS OF DIFFICULTIES WHEN DOING CUSTOMIZATIONS ON tianocore/UEFI BASED COMMERCIAL FIRMWARE PRODUCTS.** + + +# Transformation of a traditional UEFI DXE driver to **CdePkg** driver +## Adjusting the .INF file to run CdePkg features +The transformation is so easy that it could be done by a simple program or script, e.g. `Mde2Cde.py`. +![RedfishCredentialDxe.inf](RedfishCredentialDxe.inf.diff.png) + +For all **CdePkg** based DXE drivers the entry point definitions must be set to:
+(for more information read the background information below) +``` +ENTRY_POINT = _MainEntryPointDxe +IMAGE_ENTRY_POINT = _cdeCRT0UefiDxeEDK +``` + +In the `[Packages]` section the `CdePkg/CdePkg.dec` must precede the other packages, +because otherwise for **RedfishPkg** an already faultily implemented [`stdlib.h`](https://raw.githubusercontent.com/tianocore/edk2/master/RedfishPkg/PrivateInclude/Crt/stdlib.h) +leads to build errors (e.g. `atoi()` function not declarated).
+NOTE: The order of the packages determines the search-order of the include-folders. + +In the `[LibraryClasses]` section just the `CdeLib` needs to be added. `CdeLib`.lib is derived +from the original **toro C Library** binary. + +In the `[Depex]` section an additional dependency from the `CdeServices`-driver is needed. +All **CdePkg** based drivers run `printf()`, `scanf()`, `malloc()` and other code size relevant functions +from a "worker"-driver: `CdeServices`. For the DXE phase those services were provided by a protocol with the GUID: `gCdeDxeProtocolGuid` + + +**BACKGROUND INFORMATION:**
+To use existing `DEBUG()` macros in **CdePkg**-enabled drivers and to work around difficulties (unpredictability) +with the random order of .OBJ modules from the `STATIC_LIBRARY_FILES` (search libraries) from the `makefile` it was required +to override the functions below and provide them in the monolithic `IMAGE_ENTRY_POINT`.OBJ module `osifUefiDxeEntryPointEDK.obj`: +``` +_DebugPrint() CdeLib:osifUefiDxeEntryPointEDK.obj +__ModuleEntryPoint() CdeLib:osifUefiDxeEntryPointEDK.obj +_EfiMain() CdeLib:osifUefiDxeEntryPointEDK.obj +__DriverUnloadHandler() CdeLib:osifUefiDxeEntryPointEDK.obj +_DebugVPrint() CdeLib:osifUefiDxeEntryPointEDK.obj +_BaseDebugLibSerialPortConstructor() CdeLib:osifUefiDxeEntryPointEDK.obj +_DebugBPrint() CdeLib:osifUefiDxeEntryPointEDK.obj +_DebugAssert() CdeLib:osifUefiDxeEntryPointEDK.obj +_DebugClearMemory() CdeLib:osifUefiDxeEntryPointEDK.obj +_DebugAssertEnabled() CdeLib:osifUefiDxeEntryPointEDK.obj +_DebugPrintEnabled() CdeLib:osifUefiDxeEntryPointEDK.obj +_DebugCodeEnabled() CdeLib:osifUefiDxeEntryPointEDK.obj +_DebugClearMemoryEnabled() CdeLib:osifUefiDxeEntryPointEDK.obj +_DebugPrintLevelEnabled() CdeLib:osifUefiDxeEntryPointEDK.obj + . + . + . +__cdeCRT0UefiDxeEDK() CdeLib:osifUefiDxeEntryPointEDK.obj +``` + + +## Adjusting the `ENTRY_POINT`-.C file to run CdePkg features +The transformation is so easy that it could be done by a simple program or script, e.g. `Mde2Cde.py`. +![RedfishCredentialDxe.c](RedfishCredentialDxe.c.diff.png) + +There are only two things to do:
+1. rename the `xyzEntryPoint()` definition from
`EFI_STATUS EFIAPI xyzEntryPoint (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)`
to
`EFI_STATUS main(int argc, char** argv)`

+2. define and initialize `ImageHandle` and `SystemTable` as local variables in `main()`
+```EFI_HANDLE ImageHandle = (void*)argv[-2]; // get ImageHandle from CdePkg argv[-2] backdoor```
+```EFI_SYSTEM_TABLE* SystemTable = (void*)argv[-1]; // get SystemTable from CdePkg argv[-1] backdoor```
+ +## Adding a command line (`EmulatorPkg`) +This is an optional step: + +![CdeLoadOptions.h](CdeLoadOptions.h.diff.png) + +If a particular component *is not registered* in the `CdeLoadOptions.h` it gets only its +UEFI EDK2 `gEfiCallerBaseName` passed as `argv[0]` and `argc` is set to 1. + +If a particular component *is registered* in the `CdeLoadOptions.h`, like the highlighted +`RedfishCredentialDxe` in the above picture, the provided command line is processed by +function [`_cdeStr2Argcv()`](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2021-11-28/_cdeStr2Argcv.c) and passed to `main()`. + +The GUID is the `gEfiCallerIdGuid`. + +With `rejectStart = 1` a registered component does not invoke `main()`. This feature can be used to prevent a particular +component from running during POST without recompiling and updating the BIOS. + +## Adding a command line on a real platform +On a real platform the "POST command line" is placed in NVRAM, and can be modified using a +tool [`LoadOption`](https://github.com/KilianKegel/CdePkg/blob/master/LoadOptionShell/main.c). + +Build the tool using the **toro C Library** and run it in the UEFI shell: + +`LoadOption /guid 458CE95A-4942-09A9-5D21A6B16D5DAD7F /cmd "RedfishCredentialDxe /switch1 /switch2 /switch3"` + + +# Perform Standard C in **`RestJsonStructureDxe.c`** in the Emulator +```c +[561]//EFI_STATUS +[562]//EFIAPI +[563]//RestJsonStructureEntryPoint ( +[564]// IN EFI_HANDLE ImageHandle, +[565]// IN EFI_SYSTEM_TABLE *SystemTable +[566]// ) +[567]//{ +[568]EFI_STATUS main(int argc, char** argv) +[569]{ +[570] EFI_HANDLE ImageHandle = (void*)argv[-2]; +[571] IN EFI_SYSTEM_TABLE* SystemTable = (void*)argv[-1]; +[572] EFI_STATUS Status; +[573] +[574] // +[575] // CdePkg demo +[576] // +[577] if (1) { +[578] extern CHAR8* gEfiCallerBaseName; +[579] #define HUGESTRINGSIZE 65537 // buffer size 64kByte + 1 +[580] char* pBuf = realloc(NULL, HUGESTRINGSIZE); // realloc() n/a in RedFish +[581] int i; +[582] +[583] for (i = 0; i < argc; i++) // search upcase "/DEBUGBREAK" in arguments +[584] if(0 == strcmp("/DEBUGBREAK", argv[i])) +[585] __debugbreak(); +[586] +[587] for (i = 0; i < argc; i++) +[588] printf("### CdePkg demo ### gEfiCallerBaseName: \"%s\" argv[%d] %s\n", gEfiCallerBaseName, i, argv[i]); +[589] +[590] for (i = 0; i < HUGESTRINGSIZE - 1; i++) +[591] pBuf[i] = '0' + (char)(i % 32); +[592] pBuf[i - 3] = '\0'; +[593] strcat(pBuf, "\r\n"); +[594] +[595] printf("This is a very long string>>> %s\n<< +[26] +[27]typedef unsigned short wint_t; +[28]typedef unsigned short wctype_t; +[29]typedef unsigned short wctrans_t; +[30] +[31]#define WEOF ((wint_t)(0xFFFF)) +[32] +[33] +[34]int iswalnum( wint_t wc); +[35]int iswalpha( wint_t wc); +[36]int iswblank( wint_t wc ); +[37]int iswctype( wint_t wc, wctype_t desc ); +[38]int iswcntrl( wint_t wc); +[39]int iswdigit( wint_t wc); +[40]int iswgraph( wint_t wc); +[41]int iswlower( wint_t wc); +[42]int iswprint( wint_t wc); +[43]int iswpunct( wint_t wc); +[44]int iswspace( wint_t wc); +[45]int iswupper( wint_t wc); +[46]int iswxdigit( wint_t wc ); +[47] +[48]wctype_t wctype( const char *property ); +[49]wctrans_t wctrans( const char *property ); +[50] +[51]wint_t towlower( wint_t wc ); +[52]wint_t towupper( wint_t wc ); +[53] +[54]wint_t towctrans(wint_t c, wctrans_t value); +[55] +[56]// Microsoft specific - start +[57]// Bit masks for the possible character types +[58]#define _UPPER 0x01 // uppercase letter +[59]#define _LOWER 0x02 // lowercase letter +[60]#define _DIGIT 0x04 // digit[0-9] +[61]#define _SPACE 0x08 // tab, carriage return, newline, vertical tab, or form feed +[62]#define _PUNCT 0x10 // punctuation character +[63]#define _CONTROL 0x20 // control character +[64]#define _BLANK 0x40 // space char (tab is handled separately) +[65]#define _HEX 0x80 // hexadecimal digit +[66] +[67]#define _LEADBYTE 0x8000 // multibyte leadbyte +[68]#define _ALPHA (0x0100 | _UPPER | _LOWER) // alphabetic character +[69] +[70]// Microsoft specific - end +[71] +[72]#endif//_CDE_WCTYPE_H_ +``` + +NOTE: For the `isw...()` functions internally all 65536 possible parameters were adjusted to be equal to + Microsoft C Libraries originals, but only the first 256 are demonstrated here by default.
+To test more characters just add `/count ` parameter to the commandline. +```c + . + . + . + {/*rejectStart*/ 0,/*FILE_GUID, EfiCallerIdGuid*/{ 0x83FAAFBF, 0xFC4B, 0x469F, {0x89, 0x2A, 0x79, 0x8E, 0x66, 0xA6, 0xF5, 0x0A}},"RestJsonStructureDxe /count 65536 "}, + . + . + . +``` + +NOTE: The TRUTH-tables to describe entire functions behaviour is really big and stored internally in a compressed +format, that will be introduced later in an upcoming **CdePkgBlog** + +## [`wchar.h`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=360) demonstration +`wchar.h` functions are not available from [**PDCLIB**](https://github.com/DevSolar/pdclib/tree/5950958ff57391789d9a164a56cd1ed87dedaa12), +that is used in the [`StdLibPkg`](https://github.com/tianocore/edk2-staging/tree/StdLibPkg). +Beginning with line [786](https://github.com/tianocore/edk2-staging/blob/CdePkg/CdeEmuPkg/RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.c#L786) all functions defined in `wchar.h`header file run simple tests, that are: + +* [`fgetws()`](wchar_h/fgetws.c) +* [`swprintf()`](wchar_h/swprintf.c) +* [`vfwprintf()`](wchar_h/vfwprintf.c) +* [`vswprintf()`](wchar_h/vswprintf.c) +* [`vwprintf()`](wchar_h/vwprintf.c) +* [`wcscat()`](wchar_h/wcscat.c) +* [`wcschr()`](wchar_h/wcschr.c) +* [`wcscmp()`](wchar_h/wcscmp.c) +* [`wcscpy()`](wchar_h/wcscpy.c) +* [`wcscspn()`](wchar_h/wcscspn.c) +* [`wcslen()`](wchar_h/wcslen.c) +* [`wcsncat()`](wchar_h/wcsncat.c) +* [`wcsncmp()`](wchar_h/wcsncmp.c) +* [`wcsncpy()`](wchar_h/wcsncpy.c) +* [`wcsnlen()`](wchar_h/wcsnlen.c) +* [`wcspbrk()`](wchar_h/wcspbrk.c) +* [`wcsrchr()`](wchar_h/wcsrchr.c) +* [`wcsspn()`](wchar_h/wcsspn.c) +* [`wcsstr()`](wchar_h/wcsstr.c) +* [`wcstok()`](wchar_h/wcstok.c) +* [`wctob()`](wchar_h/wctob.c) +* [`wmemchr()`](wchar_h/wmemchr.c) +* [`wmemcmp()`](wchar_h/wmemcmp.c) +* [`wmemcpy()`](wchar_h/wmemcpy.c) +* [`wmemmove()`](wchar_h/wmemmove.c) +* [`wmemset()`](wchar_h/wmemset.c) +* [`wprintf()`](wchar_h/wprintf.c) + +Regrettably `wchar.h` includes the most incomplete function-set from **toro C Library**. +A lot of console related functions are not yet implemented. +The prime reason is that the Microsoft [`fwide()`](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fwide?view=msvc-170) is implemented non-conform +to [ISO/IEC 9899](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=1). +Furthermore all of the *wide* console/file functions actually access byte-wise and stretch characters to "wide" internally only. + +```c +[1]/*++ +[2] +[3] CdePkg for UEFI +[4] https://github.com/KilianKegel/CdePkg +[5] +[6] Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. +[7] SPDX-License-Identifier: BSD-2-Clause-Patent +[8] +[9]Module Name: +[10] +[11] wchar.h +[12] +[13]Abstract: +[14] +[15] Implementation of the Standard C header file for the Microsoft C Compiler VS2022 +[16] http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=360 +[17] +[18]Author: +[19] +[20] Kilian Kegel +[21] +[22]--*/ +[23]#ifndef _CDE_WCHAR_H_ +[24]#define _CDE_WCHAR_H_ +[25]#include +[26]#include +[27] +[28]typedef unsigned short wint_t; +[29] +[30]typedef struct _Mbstatet +[31]{ // state of a multibyte translation +[32] unsigned long _Wchar; +[33] unsigned short _Byte, _State; +[34]} _Mbstatet; +[35] +[36]typedef _Mbstatet mbstate_t; +[37] +[38]#ifndef NULL +[39] #define NULL ((void *)0) +[40]#endif//NULL +[41] +[42]#define WCHAR_MIN 0x0000 +[43]#define WCHAR_MAX 0xffff +[44] +[45]#ifndef WEOF +[46] #define WEOF ((wint_t)(0xFFFF)) +[47]#endif//WEOF +[48] +[49] +[50]//not yet implemented int fwprintf( FILE * stream, const wchar_t * format, ... ); +[51]//not yet implemented int fwscanf( FILE * stream, const wchar_t * format, ... ); +[52]int wprintf( const wchar_t * format, ... ); +[53]//not yet implemented int wscanf( const wchar_t * format, ... ); +[54]int swprintf( wchar_t * s, size_t n, const wchar_t * format, ... ); +[55]//not yet implemented int swscanf( const wchar_t * s, const wchar_t * format, ... ); +[56]int vfwprintf( FILE * stream, const wchar_t * format, va_list arg ); +[57]//not yet implemented int vwprintf( const wchar_t * format, va_list arg ); +[58]int vswprintf( wchar_t * s, size_t n, const wchar_t * format, va_list arg ); +[59]//not yet implemented wint_t fgetwc( FILE *stream ); +[60]//not yet implemented wchar_t *fgetws( wchar_t * s, int n, FILE * stream ); +[61]//not yet implemented wint_t fputwc( wchar_t c, FILE *stream ); +[62]//not yet implemented int fputws( const wchar_t * s, FILE * stream ); +[63]//not yet implemented wint_t getwc( FILE *stream ); +[64]//not yet implemented wint_t getwchar( void ); +[65]//not yet implemented wint_t putwc( wchar_t c, FILE *stream ); +[66]//not yet implemented wint_t putwchar( wchar_t c ); +[67]//not yet implemented wint_t ungetwc( wint_t c, FILE *stream ); +[68]//not yet implemented int fwide( FILE *stream, int mode ); +[69]//not yet implemented double wcstod( const wchar_t * nptr, wchar_t ** endptr ); +[70]//not yet implemented long int wcstol( const wchar_t * nptr, wchar_t ** endptr, int base ); +[71]//not yet implemented unsigned long int wcstoul( const wchar_t * nptr, wchar_t ** endptr, int base ); +[72]wchar_t *wcscpy( wchar_t * s1, const wchar_t * s2 ); +[73]wchar_t *wcsncpy( wchar_t * s1, const wchar_t * s2, size_t n ); +[74]wchar_t *wcscat( wchar_t * s1, const wchar_t * s2 ); +[75]wchar_t *wcsncat( wchar_t * s1, const wchar_t * s2, size_t n ); +[76]int wcscmp( const wchar_t *s1, const wchar_t *s2 ); +[77]//not yet implemented int wcscoll( const wchar_t *s1, const wchar_t *s2 ); +[78]int wcsncmp( const wchar_t *s1, const wchar_t *s2, size_t n ); +[79]size_t wcsxfrm( wchar_t * s1, const wchar_t * s2, size_t n ); +[80]wchar_t *wcschr( const wchar_t *s, wchar_t c ); +[81]size_t wcscspn( const wchar_t *s1, const wchar_t *s2 ); +[82]wchar_t *wcspbrk( const wchar_t *s1, const wchar_t *s2 ); +[83]wchar_t *wcsrchr( const wchar_t *s, wchar_t c ); +[84]size_t wcsspn( const wchar_t *s1, const wchar_t *s2 ); +[85]wchar_t *wcsstr( const wchar_t *s1, const wchar_t *s2 ); +[86]wchar_t *wcstok( wchar_t * s1, const wchar_t * s2, wchar_t ** ptr ); +[87]size_t wcslen( const wchar_t *s ); +[88]wchar_t *wmemchr( const wchar_t *s, wchar_t c, size_t n ); +[89]int wmemcmp( const wchar_t *s1, const wchar_t *s2, size_t n ); +[90]wchar_t *wmemcpy( wchar_t * s1, const wchar_t * s2, size_t n ); +[91]wchar_t *wmemmove( wchar_t *s1, const wchar_t *s2, size_t n ); +[92]wchar_t *wmemset( wchar_t *s, wchar_t c, size_t n ); +[93]//not yet implemented size_t wcsftime( wchar_t * s, size_t maxsize, const wchar_t * format, const struct tm * timeptr ); +[94]//not yet implemented wint_t btowc( int c ); +[95]int wctob( wint_t c ); +[96]//not yet implemented int mbsinit( const mbstate_t *ps ); +[97]//not yet implemented size_t mbrlen( const char * s, size_t n, mbstate_t * ps ); +[98]//not yet implemented size_t mbrtowc( wchar_t * pwc, const char * s, size_t n, mbstate_t * ps ); +[99]//not yet implemented size_t wcrtomb( char * s, wchar_t wc, mbstate_t * ps ); +[100]//not yet implemented size_t mbsrtowcs( wchar_t * dst, const char ** src, size_t len, mbstate_t * ps ); +[101]//not yet implemented size_t wcsrtombs( char * dst, const wchar_t ** src, size_t len, mbstate_t * ps ); +[102] +[103]#endif//_CDE_WCHAR_H_ +``` + +# `CDETRACE()` -- An introduction of a new DEBUG/TRACE concept for UEFI platforms +## tianocore `DEBUG()` +The `DEBUG()` trace macro in the **tianocroe/EDK2** implementation has the disadvantages listed below: +1. It can be controlled globally by choosing DEBUG vs. RELEASE build that causes side effects: + 1. In some commercial BIOS projects DEBUG mode can not be used at all, because a DEBUG built simply doesn't fit into the BIOS flash part. + That is a bad situation if no other debug tools are available. + 2. overall-DEBUG traces increase the POST time significantly + 3. irrelevant DEBUG traces cannot be suppressed. The trace log must be treated manually. + +2. It does not separate *ORIGIN* and *SEVERITY*: https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Library/DebugLib.h#L30 +```c +#define DEBUG_INIT 0x00000001 // Initialization SEVERITY +#define DEBUG_WARN 0x00000002 // Warnings SEVERITY + . + . + . +#define DEBUG_BM 0x00000400 // Boot Manager ORIGIN +#define DEBUG_BLKIO 0x00001000 // BlkIo Driver ORIGIN +#define DEBUG_NET 0x00004000 // Network Io Driver ORIGIN + . + . + . +#define DEBUG_VERBOSE 0x00400000 // Detailed debug messages that may + . // significantly impact boot performance + . + . +#define DEBUG_ERROR 0x80000000 // Error SEVERITY +``` +In customized DEBUG traces on commercial BIOS implementations *SEVERITY*-keywords like 'WARNING', 'ERROR' or 'FATAL' +are placed manually in the trace message. + +3. `DEBUG()` internally is length-limited due to a "buffer-based" implementation of `AsciiVSPrint()` and causes restrictions + 1. automatically generated [`__FILE__`](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf#page=172) *origin* can't be placed into the DEBUG()-macro + because a deep directory structure will overflow the buffer + 2. `DEBUG()` internally uses `DebugPrint()` that is not parameter checked at compile time + +## [`CDETRACE()`](https://github.com/KilianKegel/CdePkg/blob/master/Include/CDE.h#L283) +All the above mentioned characteristics are eliminated with 'CDETRACE()`.
+Additionally it provides a *condition check* like:
+```c + CDETRACE((TRCERR(EFI_SUCCESS != Status) "Something went wrong...\n")); +``` +The core idea is to use a "real" Standard C function `fprintf()`, in which cases modern C compiler (GCC too) do parameter validation at build time. +Because internally it is a buffer-less implementation the buffer cannot overflow by design and the message-length is unlimited. + +```c +#ifndef NCDETRACE +#define CDETRACE(dbgsig_msg) \ +do {\ + CDEDBGFP __cdeDbgFp = __cdeGetDbgFp dbgsig_msg; \ + if (0 == __cdeDbgFp.CdeDbg.En)\ + break;\ + if (BAR != __cdeDbgFp.CdeDbg.Msg) {\ + fprintf(__cdeDbgFp.ptr, "%s`%s(%d)`%s()`%s> ", gEfiCallerBaseName, __FILE__, __LINE__, __FUNCTION__, __cdeGetSeverityString(__cdeDbgFp)); \ + }\ + fprintf dbgsig_msg;\ + __cdeFatAss(__cdeDbgFp);\ +} while (0) +#else//NCDETRACE + + #define CDETRACE(dbgsig_msg) ((void)0) + +#endif// NCDETRACE +``` + +The first parameter determines the *SEVERITY*:
+`TRCBAR` -> bare trace
+`TRCINF` -> "INFO"
+`TRCSUC` -> "SUCCESS"
+`TRCWAR` -> "WARNING"
+`TRCERR` -> "ERROR"
+`TRCFAT` -> "FATAL"
+`TRCASS` -> "ASSERT"
+ + +The *ORIGIN* (filename, function, line number) is automatically generated. + +NOTE: This is a proposal for a better trace implementation on tianocore that currently runs on Microsoft compiler. The keyword `__FUNCTION__` is non-standard. + +## Coming up soon... +2021-11-28:
+* Using UEFI- and Standard-C-API in shell applications
+* Creating MSDOS tools.
+2021-12-12:
+* Adopting open source Visual-Studio projects to UEFI
+* Introduction of the ACPCIA port to UEFI
+ +**2021-12-19:** +* Redfish on CdePkg
+ +**2022-01-16:** +* Adopting open source Visual-Studio projects to UEFI
+* Introduction of the ACPCIA port to UEFI
+ +**2022-01-30:** +* Introduction of how to calibrate a TSC-based software timer - on IBM-AT compatible UEFI platforms + diff --git a/blogs/2021-12-19/RedfishCredentialDxe.c.diff.png b/blogs/2021-12-19/RedfishCredentialDxe.c.diff.png new file mode 100644 index 00000000000..3ebb807c14c Binary files /dev/null and b/blogs/2021-12-19/RedfishCredentialDxe.c.diff.png differ diff --git a/blogs/2021-12-19/RedfishCredentialDxe.inf.diff.png b/blogs/2021-12-19/RedfishCredentialDxe.inf.diff.png new file mode 100644 index 00000000000..7a30a369d09 Binary files /dev/null and b/blogs/2021-12-19/RedfishCredentialDxe.inf.diff.png differ diff --git a/blogs/2021-12-19/wchar_h/fgetws.c b/blogs/2021-12-19/wchar_h/fgetws.c new file mode 100644 index 00000000000..cdbb446e0b5 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/fgetws.c @@ -0,0 +1,62 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + Fgetws.c + +Abstract: + + Implementation of the Standard C function. + Get a wide string from a stream. + +Author: + + Kilian Kegel + +--*/ +#include +#include + +/** fgets +Synopsis +#include + wchar_t *fgetws(wchar_t *str, int numChars, FILE *stream); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fgets-fgetws?view=msvc-160&viewFallbackFrom=vs-2019 + The fgetws function is identical to fgets except that it gets a string of multibyte characters (if + present) from the input stream pointed to by fp, converts them to wide characters, and stores them in the + wide-character array pointed to by buf. In this case, n specifies the number of wide characters, less one, + to be read. +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fgets-fgetws?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fgets-fgetws?view=msvc-160#return-value +**/ +wchar_t* fgetws(wchar_t* s, int n, FILE* stream) { + + wchar_t c; + int i; + + do { + + for (i = 0, c = 0; i < (n - 1) && c != '\n'; i++) { + + if (1 != fread(&c, 1, 1, stream)) + break; + + s[i] = c; + } + + if (i != 0) + s[i] = '\0'; + + } while (0); + + return i == 0 ? NULL : s; +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/swprintf.c b/blogs/2021-12-19/wchar_h/swprintf.c new file mode 100644 index 00000000000..383da80412d --- /dev/null +++ b/blogs/2021-12-19/wchar_h/swprintf.c @@ -0,0 +1,57 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + Swprintf.c + +Abstract: + + Implementation of the Standard C function. + Writes formatted data to a wide string. + +Author: + + Kilian Kegel + +--*/ +#include +#include +#include +#include + +extern int vswprintf(wchar_t* pszDest, size_t dwCount, const wchar_t* pszFormat, va_list ap); + +/* swprintf() +Synopsis + #include + int swprintf(wchar_t * restrict s, size_t n, const wchar_t * restrict format, ...); +Description + The swprintf function is equivalent to fwprintf, except that the argument s + specifies an array of wide characters into which the generated output is to be written, + rather than written to a stream. No more than n wide characters are written, including a + terminating null wide character, which is always added (unless n is zero). +Returns + The swprintf function returns the number of wide characters written in the array, not + counting the terminating null wide character, or a neg ative value if an encoding error + occurred or if n or more wide characters were requested to be written. + +*/ + +int swprintf(wchar_t* pszDest, size_t dwCount, const wchar_t* pszFormat, ...) { + va_list ap; + int nRet; + + va_start(ap, pszFormat); + + nRet = vswprintf(pszDest, dwCount, pszFormat, ap); + + va_end(ap); + + return nRet; +} diff --git a/blogs/2021-12-19/wchar_h/vfwprintf.c b/blogs/2021-12-19/wchar_h/vfwprintf.c new file mode 100644 index 00000000000..7f04835e174 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/vfwprintf.c @@ -0,0 +1,107 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + Vfwprintf.c + +Abstract: + + Implementation of the Standard C function. + Write formatted output using a pointer to a list of arguments. + +Author: + + Kilian Kegel + +--*/ +#include +#include +#include + +extern void* __cdeGetAppIf(); + +static void __fputcpp(int b, void** pstream) { + fputc(b, *pstream); +} + +/** +Synopsis + #include + int vfwprintf(FILE* stream, const wchar_t* pszFormat, va_list ap); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/vfprintf-vfprintf-l-vfwprintf-vfwprintf-l?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/vfprintf-vfprintf-l-vfwprintf-vfwprintf-l?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/vfprintf-vfprintf-l-vfwprintf-vfwprintf-l?view=msvc-160#return-value +**/ +int vfwprintf(FILE* stream, const wchar_t* pszFormat, va_list ap) { + ROMPARM_VWXPRINTF RomParm = { \ + /*fForceToDataSeg */ 1 ,\ + /*fPointerIsParm */ 0 ,\ + /*fPointerIsFilePointer */ 1 ,\ + /*fCountIsParm; */ 0 ,\ + /*fAjustDifference */ 0 ,\ + /*fWide */ 1 ,\ + /*fUEFIFormat */ 0, \ + }; + int nRet = 0; + CDE_APP_IF* pCdeAppIf = __cdeGetAppIf(); + + if (NULL == pCdeAppIf) + errno = EPERM; + else do + { + _PUTCHAR* pfnOutput = NULL; + + if (CDEDBGMAGIC == (CDEDBGMAGICMASK & (size_t)stream)) + { + if (0 == (CDEDBG_EN & (size_t)stream)) + break; + + RomParm.fUEFIFormat = 0 != (CDEDBG_EFIFMT & (size_t)stream); // use EFI format specifiers? + + pfnOutput = pCdeAppIf->pCdeServices->pPutDebug; + } + else + { + switch (pCdeAppIf->DriverParm.CommParm.OSIf) + { + case PEIIF: + case DXEIF: + case SMMIF: + if ( (FILE*)CDE_STDOUT == stream + || (FILE*)CDE_STDERR == stream) + pfnOutput = pCdeAppIf->pCdeServices->pPutConOut; + stream = (void*)pCdeAppIf; + + break; + default: + pfnOutput = __fputcpp; + break; + } + } + nRet = (int)pCdeAppIf->pCdeServices->pVwxPrintf( + pCdeAppIf, // this + &RomParm, // IN ROMPARM_VWXPRINTF *pRomParm, + pszFormat, // IN const void *pszFormat, + pfnOutput, // void (*pfnDevPutChar)(UINT16/*wchar_t*/c,void** ppDest/*address of pDest*/), + stream, // UINT8 *pDest, pointer for the output function memory address or pCdeAppIf + (unsigned)-1, // unsigned dwCount, + ap // IN va_list ap + ); + + if (stdout == stream) { + pCdeAppIf->pCdeServices->pPutConOut(EOF, (void**)&pCdeAppIf); //flush to stdout + } + + } while (0); + + return nRet; +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/vswprintf.c b/blogs/2021-12-19/wchar_h/vswprintf.c new file mode 100644 index 00000000000..13185680843 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/vswprintf.c @@ -0,0 +1,83 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + Vswprintf.c + +Abstract: + + Implementation of the Standard C function. + Write formatted output using a pointer to a list of arguments. + +Author: + + Kilian Kegel + +--*/ +#include +#include +#include +#include +#include + +extern void* __cdeGetAppIf(); +extern void _CdeMemPutWChar(int c, void** ppDest); +extern void _CdeMemPutNada(int c, void** ppDest); + +static ROMPARM_VWXPRINTF RomParm = { \ +/*fForceToDataSeg */ 1 ,\ +/*fPointerIsParm */ 1 ,\ +/*fPointerIsFilePointer */ 0 ,\ +/*fCountIsParm; */ 1 ,\ +/*fAjustDifference */ 0 ,\ +/*fWide */ 1 ,\ +/*fUEFIFormat */ 0, \ +}; + +/** +Synopsis + #include + int vswprintf(wchar_t* pszDest, size_t dwCount, const wchar_t* pszFormat, va_list ap); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/vsprintf-vsprintf-l-vswprintf-vswprintf-l-vswprintf-l?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/vsprintf-vsprintf-l-vswprintf-vswprintf-l-vswprintf-l?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/vsprintf-vsprintf-l-vswprintf-vswprintf-l-vswprintf-l?view=msvc-160#return-value +**/ +int vswprintf(wchar_t* pszDest, size_t dwCount, const wchar_t* pszFormat, va_list ap) { + + unsigned nRet = UINT_MAX; + CDE_APP_IF* pCdeAppIf = __cdeGetAppIf(); + unsigned dwUsedCount = (unsigned)dwCount; + void (*pfnPutXxx)(int c, void** ppDest) = &_CdeMemPutWChar; + + do { + if (pszDest == NULL) + if (dwCount == 0) + dwUsedCount = UINT_MAX, pfnPutXxx = &_CdeMemPutNada; // count only, don't write + else + break; + nRet = (int)pCdeAppIf->pCdeServices->pVwxPrintf( + pCdeAppIf, //this + &RomParm, //IN ROMPARM_VWXPRINTF *pRomParm, + pszFormat, //IN const void *pszFormat, + pfnPutXxx, //void (*pfnDevPutChar)(unsigned short/*wchar_t*/c,void** ppDest/*address of pDest*/), + pszDest, //unsigned char *pDest, + (unsigned)dwUsedCount, //unsigned dwCount, + ap //IN va_list ap + ); + if (pszDest != NULL) { + if (dwUsedCount > nRet&& nRet != UINT_MAX) + pszDest[nRet] = L'\0'; + } + } while (0); + + return (int)nRet; +} diff --git a/blogs/2021-12-19/wchar_h/vwprintf.c b/blogs/2021-12-19/wchar_h/vwprintf.c new file mode 100644 index 00000000000..c30a3299237 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/vwprintf.c @@ -0,0 +1,42 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + Vwprintf.c + +Abstract: + + Implementation of the Standard C function. + Writes formatted output by using a pointer to a list of arguments. + +Author: + + Kilian Kegel + +--*/ +#include +#include + +extern int vfwprintf(FILE* stream, const wchar_t* pszFormat, va_list ap); + +/** +Synopsis + #include + int vwprintf(const wchar_t* pszFormat, va_list ap); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/vprintf-vprintf-l-vwprintf-vwprintf-l?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/vprintf-vprintf-l-vwprintf-vwprintf-l?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/vprintf-vprintf-l-vwprintf-vwprintf-l?view=msvc-160#return-value +**/ +int vwprintf(const wchar_t* pszFormat, va_list ap) { + + return vfwprintf(stdout, pszFormat, ap); +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wcscat.c b/blogs/2021-12-19/wchar_h/wcscat.c new file mode 100644 index 00000000000..9dc0bf72911 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcscat.c @@ -0,0 +1,39 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsCat.c + +Abstract: + + Implementation of the Standard C function. + Appends a wide string. + +Author: + + Kilian Kegel + +--*/ +#include + +/** +Synopsis + #include + wchar_t* wcscat(wchar_t* s1, const wchar_t* s2); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcat-wcscat-mbscat?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcat-wcscat-mbscat?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcat-wcscat-mbscat?view=msvc-160#return-value +**/ +wchar_t* wcscat(wchar_t* s1, const wchar_t* s2) { + wcscpy(&s1[wcslen(s1)], s2); + return s1; +} diff --git a/blogs/2021-12-19/wchar_h/wcschr.c b/blogs/2021-12-19/wchar_h/wcschr.c new file mode 100644 index 00000000000..ce044c426e4 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcschr.c @@ -0,0 +1,54 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsChr.c + +Abstract: + + Implementation of the Standard C function. + Finds a character in a wide string + +Author: + + Kilian Kegel + +--*/ +#include +#include +#include + +extern wchar_t* wcspbrk(const wchar_t* pszStr, const wchar_t* pszSet); + +/** +Synopsis + #include + wchar_t* wcschr(const wchar_t* wcs, wchar_t c); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strchr-wcschr-mbschr-mbschr-l?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strchr-wcschr-mbschr-mbschr-l?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strchr-wcschr-mbschr-mbschr-l?view=msvc-160#return-value +**/ +wchar_t* wcschr(const wchar_t* wcs, wchar_t c) { + + wchar_t buffer[2] = { '\0','\0' }; + wchar_t* pRet; + + buffer[0] = (wchar_t)c; + if ('\0' != c) { + pRet = wcspbrk(wcs, &buffer[0]); + } + else { + pRet = &((wchar_t*)/*cast due "warning C4090: '=' : different 'const' qualifiers"*/wcs)[wcslen(wcs)]; + } + + return pRet; +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wcscmp.c b/blogs/2021-12-19/wchar_h/wcscmp.c new file mode 100644 index 00000000000..22afdff6a01 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcscmp.c @@ -0,0 +1,52 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsCmp.c + +Abstract: + + Implementation of the Standard C function. + Compare wide strings. + + +Author: + + Kilian Kegel + +--*/ +#include +#include +#include +#include + +static ROMPARM_MEMSTRXCMP ROMPARM = { + /*fForceToDataSeg*/ 1 ,\ + /*fCountIsParm*/ 0, \ + /*fCaseSensitive*/ 1, \ + /*fBreakOnZero*/ 1, \ + /*fAjustDifference*/1, \ + /*fWide*/ 1 }; +/** +Synopsis + #include + int wcscmp(const wchar_t* pszDst, const wchar_t* pszSrc); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcmp-wcscmp-mbscmp?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcmp-wcscmp-mbscmp?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcmp-wcscmp-mbscmp?view=msvc-160#return-value +**/ +int wcscmp(const wchar_t* pszDst, const wchar_t* pszSrc) { + CDE_APP_IF* pCdeAppIf = __cdeGetAppIf(); + + return pCdeAppIf->pCdeServices->pMemStrxCmp(&ROMPARM, (void*)pszDst, (void*)pszSrc, (size_t)-1); + +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wcscpy.c b/blogs/2021-12-19/wchar_h/wcscpy.c new file mode 100644 index 00000000000..139d0917c0e --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcscpy.c @@ -0,0 +1,44 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsCpy.c + +Abstract: + + Implementation of the Standard C function. + Copies a wide string. + +Author: + + Kilian Kegel + +--*/ +#include +#include +#include +#include + +/** +Synopsis + #include + wchar_t* wcscpy(wchar_t* pszDst, const wchar_t* pszSrc); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcpy-wcscpy-mbscpy?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcpy-wcscpy-mbscpy?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcpy-wcscpy-mbscpy?view=msvc-160#return-value +**/ +wchar_t* wcscpy(wchar_t* pszDst, const wchar_t* pszSrc) { + CDE_APP_IF* pCdeAppIf = __cdeGetAppIf(); + + return (wchar_t*)pCdeAppIf->pCdeServices->pMemStrxCpy(BOZ + WID, pszDst, pszSrc, (size_t)-1); + +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wcscspn.c b/blogs/2021-12-19/wchar_h/wcscspn.c new file mode 100644 index 00000000000..7fb7d7818a8 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcscspn.c @@ -0,0 +1,55 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsCSpn.c + +Abstract: + + Implementation of the Standard C function. + Returns the index of the first occurrence in a string, of a character that belongs to a set of characters. + +Author: + + Kilian Kegel + +--*/ +#include +#include + +extern void* __cdeGetAppIf(); + +/** + +Synopsis + #include + size_t wcscspn(const wchar_t *s1, const wchar_t *s2); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcspn-wcscspn-mbscspn-mbscspn-l?view=msvc-160 + The wcscspn function computes the length of the maximum initial segment of the wide + string pointed to by s1 which consists entirely of wide characters not from the wide + string pointed to by s2. +Returns + The wcscspn function returns the length of the segment. + + @param[in] char *s1 + + @param[in] char *s2 + + @retval size_t, lenght of block + +**/ + +size_t wcscspn(const wchar_t* pszStr, const wchar_t* pszSet) { + CDE_APP_IF* pCdeAppIf = __cdeGetAppIf(); + wchar_t* p; + p = (wchar_t*)pCdeAppIf->pCdeServices->pWcsStrPbrkSpn(WID, (void*)pszStr, (void*)pszSet); + + return p ? p - pszStr : 0; +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wcslen.c b/blogs/2021-12-19/wchar_h/wcslen.c new file mode 100644 index 00000000000..5dfc5667095 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcslen.c @@ -0,0 +1,44 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsLen.c + +Abstract: + + Implementation of the Standard C function. + Gets the length of a wide string, + +Author: + + Kilian Kegel + +--*/ +#include +#include +#include + +/** +Synopsis + #include + size_t wcslen(const short* pszBuffer); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strlen-wcslen-mbslen-mbslen-l-mbstrlen-mbstrlen-l?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strlen-wcslen-mbslen-mbslen-l-mbstrlen-mbstrlen-l?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strlen-wcslen-mbslen-mbslen-l-mbstrlen-mbstrlen-l?view=msvc-160#return-value +**/ +size_t wcslen(const short* pszBuffer) { + int i = 0; + + while (pszBuffer[i] != '\0') + i++; + return (size_t)i; +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wcsncat.c b/blogs/2021-12-19/wchar_h/wcsncat.c new file mode 100644 index 00000000000..d7660dd2754 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcsncat.c @@ -0,0 +1,45 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsNCat.c + +Abstract: + + Implementation of the Standard C function. + Appends characters of a wide string. + +Author: + + Kilian Kegel + +--*/ +#include + +/** +Synopsis + #include + wchar_t* wcsncat(wchar_t* s1, const wchar_t* s2, size_t n); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strncat-strncat-l-wcsncat-wcsncat-l-mbsncat-mbsncat-l?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strncat-strncat-l-wcsncat-wcsncat-l-mbsncat-mbsncat-l?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strncat-strncat-l-wcsncat-wcsncat-l-mbsncat-mbsncat-l?view=msvc-160#return-value +**/ +wchar_t* wcsncat(wchar_t* s1, const wchar_t* s2, size_t n) { + size_t size1 = wcslen(s1); + size_t size2 = wcslen(s2); + size_t i = size2 < n ? size2 : n; + + wcsncpy(&s1[size1], s2, i); + s1[size1 + i] = 0; + + return s1; +} diff --git a/blogs/2021-12-19/wchar_h/wcsncmp.c b/blogs/2021-12-19/wchar_h/wcsncmp.c new file mode 100644 index 00000000000..cd1555b5dbf --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcsncmp.c @@ -0,0 +1,52 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsNCmp.c + +Abstract: + + Implementation of the Standard C function. + Appends characters of a wide string. + +Author: + + Kilian Kegel + +--*/ +#include +#include +#include +#include + +static ROMPARM_MEMSTRXCMP ROMPARM = { + /*fForceToDataSeg*/ 1 , \ + /*fCountIsParm*/ 1, \ + /*fCaseSensitive*/ 1, \ + /*fBreakOnZero*/ 1, \ + /*fAjustDifference*/1, \ + /*fWide*/ 1 }; + +/** +Synopsis + #include + int wcsncmp(const wchar_t* pszDst, const wchar_t* pszSrc, size_t count); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strncmp-wcsncmp-mbsncmp-mbsncmp-l?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strncmp-wcsncmp-mbsncmp-mbsncmp-l?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strncmp-wcsncmp-mbsncmp-mbsncmp-l?view=msvc-160#return-value +**/ +int wcsncmp(const wchar_t* pszDst, const wchar_t* pszSrc, size_t count) { + CDE_APP_IF* pCdeAppIf = __cdeGetAppIf(); + + return pCdeAppIf->pCdeServices->pMemStrxCmp(&ROMPARM, (void*)pszDst, (void*)pszSrc, count); + +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wcsncpy.c b/blogs/2021-12-19/wchar_h/wcsncpy.c new file mode 100644 index 00000000000..232c846291b --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcsncpy.c @@ -0,0 +1,44 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsNCpy.c + +Abstract: + + Implementation of the Standard C function. + Copy characters of one wide string to another + +Author: + + Kilian Kegel + +--*/ +#include +#include +#include +#include + +/** +Synopsis + #include + int wcsncmp(const wchar_t* pszDst, const wchar_t* pszSrc, size_t count); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strncpy-strncpy-l-wcsncpy-wcsncpy-l-mbsncpy-mbsncpy-l?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strncpy-strncpy-l-wcsncpy-wcsncpy-l-mbsncpy-mbsncpy-l?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strncpy-strncpy-l-wcsncpy-wcsncpy-l-mbsncpy-mbsncpy-l?view=msvc-160#return-value +**/ +wchar_t* wcsncpy(wchar_t* pszDst, const wchar_t* pszSrc, size_t n) { + CDE_APP_IF* pCdeAppIf = __cdeGetAppIf(); + + return (wchar_t*)pCdeAppIf->pCdeServices->pMemStrxCpy(WID + BOZ, pszDst, pszSrc, n); + +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wcsnlen.c b/blogs/2021-12-19/wchar_h/wcsnlen.c new file mode 100644 index 00000000000..073ae1cd3ce --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcsnlen.c @@ -0,0 +1,46 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsNLen.c + +Abstract: + + Implementation of the Microsoft / POSIX C function. + Gets the length of a wide string. + +Author: + + Kilian Kegel + +--*/ +#include + +/** +Synopsis + #include + size_t wcsnlen(const wchar_t* pwcsBuffer, size_t n); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strnlen-strnlen-s?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strnlen-strnlen-s?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strnlen-strnlen-s?view=msvc-160#return-value +**/ +size_t wcsnlen(const wchar_t* pwcsBuffer, size_t n) { + size_t i = 0; + + while (pwcsBuffer[i] != '\0') + if (i == n) + break; + else + i++; + + return i; +} diff --git a/blogs/2021-12-19/wchar_h/wcspbrk.c b/blogs/2021-12-19/wchar_h/wcspbrk.c new file mode 100644 index 00000000000..52a7ee6aaf7 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcspbrk.c @@ -0,0 +1,55 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsPbrk.c + +Abstract: + + Implementation of the Standard C function. + Scans wide strings for characters in specified character sets. + +Author: + + Kilian Kegel + +--*/ +#include +#include +extern void* __cdeGetAppIf(); + +/** + +Synopsis + #include + wchar_t *wcspbrk(const wchar_t *s1, const wchar_t *s2); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strpbrk-wcspbrk-mbspbrk-mbspbrk-l?view=msvc-160 + The wcspbrk function locates the first occurrence in the wide string pointed to by s1 of + any wide character from the wide string pointed to by s2. +Returns + The wcspbrk function returns a pointer to the wide character in s1, or a null pointer if + no wide character from s2 occurs in s1. + + @param[in] wchar_t *s1 + + @param[in] wchar_t *s2 + + @retval size_t, lenght of block + +**/ + +wchar_t* wcspbrk(const wchar_t* pszStr, const wchar_t* pszSet) { + CDE_APP_IF* pCdeAppIf = __cdeGetAppIf(); + wchar_t* p; + + p = (wchar_t*)pCdeAppIf->pCdeServices->pWcsStrPbrkSpn(WID, (void*)pszStr, (void*)pszSet); + + return *p == '\0' ? NULL : p; +} diff --git a/blogs/2021-12-19/wchar_h/wcsrchr.c b/blogs/2021-12-19/wchar_h/wcsrchr.c new file mode 100644 index 00000000000..b090d010bc6 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcsrchr.c @@ -0,0 +1,63 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsRChr.c + +Abstract: + + Implementation of the Standard C function. + Scans a wide string for the last occurrence of a character. + +Author: + + Kilian Kegel + +--*/ +#include +#include +#include + +/** wcsrchr() +Synopsis + #include + wchar_t *wcsrchr(const wchar_t *s, wchar_t c); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strrchr-wcsrchr-mbsrchr-mbsrchr-l?view=msvc-160 + The wcsrchr function locates the last occurrence of c + in the wide string pointed to by s. + The terminating null wide character is considered to be part of the wide string. +Returns + The wcsrchr function returns a pointer to the wide character, or a null pointer if + c does not occur in the wide string. + + @param[in] const char *str + + @param[in] int c + + @retval Success: pointer to the located charachter + + @retval Failure: NULL + +**/ +wchar_t* wcsrchr(const wchar_t* wcs, wchar_t c) { + CDE_APP_IF* pCdeAppIf = __cdeGetAppIf(); + wchar_t buffer[2] = { '\0','\0' }; + wchar_t* pRet; + + buffer[0] = (wchar_t)c; + if ('\0' != c) { + pRet = pCdeAppIf->pCdeServices->pWcsStrPbrkSpn(TDN + WID, (void*)wcs, (void*)&buffer[0]); + } + else { + pRet = &((wchar_t*)/*cast due "warning C4090: '=' : different 'const' qualifiers"*/wcs)[wcslen(wcs)]; + } + + return pRet; +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wcsspn.c b/blogs/2021-12-19/wchar_h/wcsspn.c new file mode 100644 index 00000000000..b95ed8fdcd8 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcsspn.c @@ -0,0 +1,55 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsSpn.c + +Abstract: + + Implementation of the Standard C function. + Returns the index of the first character, in a wide string, that does not belong to a set of characters. + +Author: + + Kilian Kegel + +--*/ +#include +#include +extern void* __cdeGetAppIf(); + +/** Brief description of the function’s purpose. + +Synopsis + #include + size_t wcsspn(const wchar_t *s1, const wchar_t *s2); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strspn-wcsspn-mbsspn-mbsspn-l?view=msvc-160 + The wcsspn function computes the length of the maximum initial segment of the wide + string pointed to by s1 which consists entirely of wide characters from the wide string + pointed to by s2. +Returns + The wcsspn function returns the length of the segment. + + @param[in] char *s1 + + @param[in] char *s2 + + @retval size_t, lenght of block + +**/ + +size_t wcsspn(const wchar_t* pszStr, const wchar_t* pszSet) { + wchar_t* p; + CDE_APP_IF* pCdeAppIf = __cdeGetAppIf(); + + p = (wchar_t*)pCdeAppIf->pCdeServices->pWcsStrPbrkSpn(WID + INV, (void*)pszStr, (void*)pszSet); + + return p ? p - pszStr : 0; +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wcsstr.c b/blogs/2021-12-19/wchar_h/wcsstr.c new file mode 100644 index 00000000000..f159a65e7d1 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcsstr.c @@ -0,0 +1,64 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsStr.c + +Abstract: + + Implementation of the Standard C function. + Returns a pointer to the first occurrence of a search wide string in a wide string. + +Author: + + Kilian Kegel + +--*/ +#include + +/** +Synopsis + #include + wchar_t* wcsstr(const wchar_t* pszStr, const wchar_t* pszSubStr); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strstr-wcsstr-mbsstr-mbsstr-l?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strstr-wcsstr-mbsstr-mbsstr-l?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strstr-wcsstr-mbsstr-mbsstr-l?view=msvc-160#return-value +**/ +wchar_t* wcsstr(const wchar_t* pszStr, const wchar_t* pszSubStr) { + const wchar_t* pRet = NULL; + wchar_t* pPos = (wchar_t*)&pszStr[-1]; + int i; + + do { + + if ('\0' == pszSubStr[0]) { + pRet = pszStr; + break; + } + + while (*++pPos) { + + pszStr = pPos; + i = 0; + + while (pszStr[i] && pszSubStr[i] && (pszStr[i] == pszSubStr[i])) + i++; + + if ('\0' == pszSubStr[i]) { + pRet = pPos; + break; + } + } + } while (0); + + return (wchar_t*)pRet; +} diff --git a/blogs/2021-12-19/wchar_h/wcstok.c b/blogs/2021-12-19/wchar_h/wcstok.c new file mode 100644 index 00000000000..eca88cd7f70 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wcstok.c @@ -0,0 +1,49 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WcsTok.c + +Abstract: + + Implementation of the Standard C function. + Finds the next token in a wide string, + +Author: + + Kilian Kegel + +--*/ +#include +#include +extern void* __cdeGetAppIf(); + +static ROMPARM_WCSSTRTOK ROMPARM = { + /*fForceToDataSeg */ 1 ,\ + /*fWide */ sizeof(wchar_t) > 1 ,\ +}; + +/** +Synopsis + #include + wchar_t* wcstok(wchar_t* pszStr, const wchar_t* pszSet, wchar_t** ppLast); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtok-strtok-l-wcstok-wcstok-l-mbstok-mbstok-l?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtok-strtok-l-wcstok-wcstok-l-mbstok-mbstok-l?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtok-strtok-l-wcstok-wcstok-l-mbstok-mbstok-l?view=msvc-160#return-value +**/ +wchar_t* wcstok(wchar_t* pszStr, const wchar_t* pszSet, wchar_t** ppLast) { + + CDE_APP_IF* pCdeAppIf = __cdeGetAppIf(); + + return (wchar_t*)pCdeAppIf->pCdeServices->pWcsStrTok(pCdeAppIf, pszStr, pszSet, ppLast, &ROMPARM); + +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wctob.c b/blogs/2021-12-19/wchar_h/wctob.c new file mode 100644 index 00000000000..aad2e60204a --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wctob.c @@ -0,0 +1,43 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + wctob.c + +Abstract: + + Implementation of the Standard C function. + Determines if a wide character corresponds to a multibyte character and returns its multibyte character representation. + +Author: + + Kilian Kegel + +--*/ +#include + +extern int wctomb(char* pmb, wchar_t wc); + +/** +Synopsis + #include + wchar_t* wcstok(wchar_t* pszStr, const wchar_t* pszSet, wchar_t** ppLast); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/wctob?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/wctob?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/wctob?view=msvc-160#return-value +**/ +int wctob(wchar_t wc) +{ + char c; + + return 1 == wctomb(&c, wc) ? 0xFF & c : -1; +} diff --git a/blogs/2021-12-19/wchar_h/wmemchr.c b/blogs/2021-12-19/wchar_h/wmemchr.c new file mode 100644 index 00000000000..181b88e2845 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wmemchr.c @@ -0,0 +1,57 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WMemChr.c + +Abstract: + + Implementation of the Standard C function. + Find wide characters in a buffer. + +Author: + + Kilian Kegel + +--*/ +#include + +/** wmemchr +Synopsis + #include + wchar_t *wmemchr(const wchar_t *s, wchar_t c,size_t n); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memchr-wmemchr?view=msvc-160 + The wmemchr function locates the first occurrence of c in the initial n wide characters of + the object pointed to by s. +Returns + The wmemchr function returns a pointer to the located wide character, or a null pointer if + the wide character does not occur in the object. + + @param[in] const wchar_t *str + + @param[in] wchar_t c + + @param[in] size_t n + + @retval Success: pointer to the located charachter + + @retval Failure: NULL + +**/ +wchar_t* wmemchr(const wchar_t* s, wchar_t c, size_t n) { + while (n) { + if (*s == c) + break; + n--; + s++; + } + + return n == 0 ? NULL : (wchar_t*)s; +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wmemcmp.c b/blogs/2021-12-19/wchar_h/wmemcmp.c new file mode 100644 index 00000000000..d8c1b217660 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wmemcmp.c @@ -0,0 +1,49 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WMemCmp.c + +Abstract: + + Implementation of the Standard C function. + Compares characters in two buffers. + +Author: + + Kilian Kegel + +--*/ +#include + +static ROMPARM_MEMSTRXCMP ROMPARM = { + /*fForceToDataSeg*/ 1 ,\ + /*fCountIsParm*/ 1, \ + /*fCaseSensitive*/ 1, \ + /*fBreakOnZero*/ 0, \ + /*fAjustDifference*/1, \ + /*fWide*/ 1 }; + +/** +Synopsis + #include + int wmemcmp(const char* pszDst, const char* pszSrc, size_t count); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memcmp-wmemcmp?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memcmp-wmemcmp?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memcmp-wmemcmp?view=msvc-160#return-value +**/ +int wmemcmp(const char* pszDst, const char* pszSrc, size_t count) { + CDE_APP_IF* pCdeAppIf = __cdeGetAppIf(); + + return pCdeAppIf->pCdeServices->pMemStrxCmp(&ROMPARM, pszDst, pszSrc, count); + +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wmemcpy.c b/blogs/2021-12-19/wchar_h/wmemcpy.c new file mode 100644 index 00000000000..5beaa901ed1 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wmemcpy.c @@ -0,0 +1,43 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WMemCpy.c + +Abstract: + + Implementation of the Standard C function. + Copies bytes between buffers. + +Author: + + Kilian Kegel + +--*/ +#include + +/** +Synopsis + #include + wchar_t* wmemcpy(wchar_t* s1, const wchar_t* s2, size_t n); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memcpy-wmemcpy?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memcpy-wmemcpy?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memcpy-wmemcpy?view=msvc-160#return-value +**/ +wchar_t* wmemcpy(wchar_t* s1, const wchar_t* s2, size_t n) { + size_t i; + + for (i = 0; i < n; i++) { + s1[i] = s2[i]; + } + return s1; +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wmemmove.c b/blogs/2021-12-19/wchar_h/wmemmove.c new file mode 100644 index 00000000000..742e6e129a6 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wmemmove.c @@ -0,0 +1,72 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WMemMove.c + +Abstract: + + Implementation of the Standard C function. + Moves one buffer to another. + +Author: + + Kilian Kegel + +--*/ +#include +#include + +/** + +Synopsis + #include + wchar_t *wmemmove(wchar_t *s1, const wchar_t *s2,size_t n); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memmove-wmemmove?view=msvc-160 + The wmemmove function copies n wide characters from the object pointed to by s2 to + the object pointed to by s1. Copying takes place as if the n wide characters from the + object pointed to by s2 are first copied into a temporary array of n wide characters that + does not overlap the objects pointed to by s1 or s2, and then the n wide characters from + the temporary array are copied into the object pointed to by s1. +Returns + The wmemmove function returns the value of s1. + + @param[in] void *s buffer address + int c fill + size_t n number of characters + + @retval void *s + +**/ + +wchar_t* wmemmove(wchar_t* pDst, const wchar_t* pSrc, size_t n) { + CDE_APP_IF* pCdeAppIf = __cdeGetAppIf(); + wchar_t* s = (wchar_t*)pSrc, * d = pDst; + int preset; + + if (pSrc < pDst) { + + preset = WID + CIP + TDN; + s = &s[n - 1]; + d = &d[n - 1]; + + } + else { + + preset = WID + CIP; + s = &s[0]; + d = &d[0]; + } + + pCdeAppIf->pCdeServices->pMemStrxCpy(preset, d, s, n); + + return pDst; + +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wmemset.c b/blogs/2021-12-19/wchar_h/wmemset.c new file mode 100644 index 00000000000..94e2b4daa93 --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wmemset.c @@ -0,0 +1,50 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + WMemSet.c + +Abstract: + + Implementation of the Standard C function. + Sets buffers to a specified wide character. + +Author: + + Kilian Kegel + +--*/ +#include + +/** + +Synopsis + #include + wchar_t *wmemset(wchar_t *s, wchar_t c, size_t n); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memset-wmemset?view=msvc-160 + The wmemset function copies the value of c into each of the first n wide characters of + the object pointed to by s. +Returns + The wmemset function returns the value of s. + + @param[in] void *s buffer address + int c fill + size_t n number of characters + + @retval wchar_t *s + +**/ +wchar_t* wmemset(wchar_t* s, wchar_t c, size_t n) { + size_t i; + + for (i = 0; i < n; i++) + s[i] = c; + return s; +} \ No newline at end of file diff --git a/blogs/2021-12-19/wchar_h/wprintf.c b/blogs/2021-12-19/wchar_h/wprintf.c new file mode 100644 index 00000000000..906e3669f9f --- /dev/null +++ b/blogs/2021-12-19/wchar_h/wprintf.c @@ -0,0 +1,59 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + Wprintf.c + +Abstract: + + Implementation of the Standard C function. + Prints formatted output to the standard output stream. + +Author: + + Kilian Kegel + +--*/ +#include +#include + +static ROMPARM_VWXPRINTF RomParm = { \ +/*fForceToDataSeg */ 1 ,\ +/*fPointerIsParm */ 0 ,\ +/*fPointerIsFilePointer */ 0 ,\ +/*fCountIsParm; */ 0 ,\ +/*fAjustDifference */ 0 ,\ +/*fWide */ 1 ,\ +/*fUEFIFormat */ 0, \ +}; + +/** +Synopsis + #include + wchar_t* wmemcpy(wchar_t* s1, const wchar_t* s2, size_t n); +Description + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/printf-printf-l-wprintf-wprintf-l?view=msvc-160 +Parameters + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/printf-printf-l-wprintf-wprintf-l?view=msvc-160#parameters +Returns + https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/printf-printf-l-wprintf-wprintf-l?view=msvc-160#return-value +**/ +int wprintf(const wchar_t* pszFormat, ...) { + + va_list ap; + int nRet = 0; + + va_start(ap, pszFormat); + + nRet = vfwprintf(stdout, pszFormat, ap); + + va_end(ap); + + return nRet; +} \ No newline at end of file diff --git a/blogs/2021-12-19/wctype_h/iswalnum.c b/blogs/2021-12-19/wctype_h/iswalnum.c new file mode 100644 index 00000000000..ba2185b89f3 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/iswalnum.c @@ -0,0 +1,51 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + iswalnum.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#define _CTYPE_DISABLE_MACROS +#include + +/** Brief description of the function’s purpose. + +Synopsis + #include + int iswalnum(wint_t wc); +Description + The iswalnum function tests for any wide character for which iswalpha or + iswdigit is true. + + @param[in] c character to test for alnum + + @retval eighter ISLOWER or ISUPPER or + ISDIGIT if alnum letter + + @retval 0 if not + +**/ +int iswalnum(wint_t c) { + int nRet0 = 0, nRet1 = 0; + + nRet0 = iswalpha(c); + + if (0 == nRet0) + nRet1 = iswdigit(c); + + return nRet0 | nRet1; +} diff --git a/blogs/2021-12-19/wctype_h/iswalpha.c b/blogs/2021-12-19/wctype_h/iswalpha.c new file mode 100644 index 00000000000..5313ddd24be --- /dev/null +++ b/blogs/2021-12-19/wctype_h/iswalpha.c @@ -0,0 +1,69 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + iswalpha.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#define _CTYPE_DISABLE_MACROS +#include + +#include +#include <_wctype.h> + +extern char _cdeChkIsWxTbl(ISWX_TRUTH_TABLE* pIswxTbl, wint_t c); + +extern ISWX_TRUTH_TABLE iswalphacaseless_dflt_tbl[]; + +/** Brief description of the function’s purpose. + +Synopsis + #include + int iswalpha(wint_t wc); +Description + The iswalpha function tests for any wide character for which iswupper or + iswlower is true, or any wide character that is one of a locale-specific set of alphabetic + wide characters for which none of iswcntrl, iswdigit, iswpunct, or iswspace + is true. + + @param[in] c character to test for alpha + + @retval eighter ISLOWER or ISUPPER if upcase letter + + @retval 0 if not + +**/ +ISWX_TRUTH_TABLE* gpTBLiswalphacaseless = iswalphacaseless_dflt_tbl; + +int iswalpha(wint_t c) { + + int nRet0 = 0, nRet1 = 0, nRet2 = 0; + + nRet0 = (_ALPHA & ~(_UPPER | _LOWER)) * _cdeChkIsWxTbl(gpTBLiswalphacaseless, c); + + if (0 == nRet0) { + + nRet1 = iswupper(c); + + nRet2 = iswlower(c) /*&& !(iswcntrl(c) | iswdigit(c) | iswpunct(c) | iswspace(c)*/; + } + + if (nRet0 | nRet1 | nRet2) { + nRet0 |= (_ALPHA & ~(_UPPER | _LOWER)); + } + return nRet0 | nRet1 | nRet2; +} diff --git a/blogs/2021-12-19/wctype_h/iswblank.c b/blogs/2021-12-19/wctype_h/iswblank.c new file mode 100644 index 00000000000..17502c78514 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/iswblank.c @@ -0,0 +1,56 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + iswblank.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#define _CTYPE_DISABLE_MACROS +#include + +#include +#include <_wctype.h> + +extern char _cdeChkIsWxTbl(ISWX_TRUTH_TABLE* pIswxTbl, wint_t c); + +extern ISWX_TRUTH_TABLE iswblank_dflt_tbl[]; + +/** Brief description of the function’s purpose. + +Synopsis + #include + int iswblank(wint_t wc); +Description + The iswblank function tests for any wide character that is a standard blank wide + character or is one of a locale-specific set of wide characters for which iswspace is true + and that is used to separate words within a line of text. The standard blank wide + characters are the following: space (L' '), and horizontal tab (L'\t'). In the "C" + locale, iswblank returns true only for the standard blank characters. + + @param[in] wc + + @retval _BLANK if blank + + @retval 0 if not + +**/ +ISWX_TRUTH_TABLE* gpTBLiswblank = iswblank_dflt_tbl; + +int iswblank(wint_t c) { + + return _BLANK * _cdeChkIsWxTbl(gpTBLiswblank, c); +} diff --git a/blogs/2021-12-19/wctype_h/iswcntrl.c b/blogs/2021-12-19/wctype_h/iswcntrl.c new file mode 100644 index 00000000000..04c37b8ea4f --- /dev/null +++ b/blogs/2021-12-19/wctype_h/iswcntrl.c @@ -0,0 +1,56 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + iswcntrl.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#define _CTYPE_DISABLE_MACROS +#include + +#include +#include <_wctype.h> + +extern char _cdeChkIsWxTbl(ISWX_TRUTH_TABLE* pIswxTbl, wint_t c); + +extern ISWX_TRUTH_TABLE iswcntrl_dflt_tbl[]; + +/** Brief description of the function’s purpose. + +Synopsis + #include + int iswcntrl(wint_t wc); +Description + The iswcntrl function tests for any control wide character. + + The function returns non-zero if c is any of: + BEL BS CR FF HT NL VT + or any other implementation-defined control character. + + @param[in] c character to test for _CONTROL + + @retval _CONTROL if cntrl letter + + @retval 0 if not + +**/ +ISWX_TRUTH_TABLE* gpTBLiswcntrl = iswcntrl_dflt_tbl; + +int iswcntrl(wint_t c) { + + return _CONTROL * _cdeChkIsWxTbl(gpTBLiswcntrl, c); +} diff --git a/blogs/2021-12-19/wctype_h/iswctype.c b/blogs/2021-12-19/wctype_h/iswctype.c new file mode 100644 index 00000000000..ba723f28363 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/iswctype.c @@ -0,0 +1,91 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + iswctype.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#define _CTYPE_DISABLE_MACROS +#include + +#include +#include <_wctype.h> +#include + +#define ELC(x)/*element count*/ (sizeof(x) / sizeof(x[0])) +extern WCPROPERTY _wcproperty[]; + +/** Brief description of the function’s purpose. + +Synopsis + #include + int iswctype(wint_t wc, wctype_t desc); +Description + The iswctype function determines whether the wide character wc has the property + described by desc. The current setting of the LC_CTYPE category shall be the same as + during the call to wctype that returned the value desc. + Each of the following expressions has a truth-value equivalent to the call to the wide + character classification function (7.25.2.1) in the comment that follows the expression: + iswctype(wc, wctype("alnum")) // iswalnum(wc) + iswctype(wc, wctype("alpha")) // iswalpha(wc) + iswctype(wc, wctype("blank")) // iswblank(wc) + iswctype(wc, wctype("cntrl")) // iswcntrl(wc) + iswctype(wc, wctype("digit")) // iswdigit(wc) + iswctype(wc, wctype("graph")) // iswgraph(wc) + iswctype(wc, wctype("lower")) // iswlower(wc) + iswctype(wc, wctype("print")) // iswprint(wc) + iswctype(wc, wctype("punct")) // iswpunct(wc) + iswctype(wc, wctype("space")) // iswspace(wc) + iswctype(wc, wctype("upper")) // iswupper(wc) + iswctype(wc, wctype("xdigit")) // iswxdigit(wc) +Returns + The iswctype function returns nonzero (true) if and only if the value of the wide + character wc has the property described by desc. + +@param[in] const char *property -> "alpha","alnum","blank","cntrl","digit","graph","lower","print","punct","space","upper","xdigit" + +@retval non zero on success + +@retval 0 if not + +**/ +#include +int iswctype(wint_t wc, wctype_t desc) { + int nRet = 0; + int i, j, mask; + + if (0 != desc) { + for (i = 0, mask = (1 << i); i < WEOF + 1; mask = (1 << ++i)) { + + if (!(mask & desc)) + continue; + + for (j = 0; NULL != _wcproperty[j].szProperty; j++) { + + if (mask & _wcproperty[j].type) { + + if (0 != (mask & (_wcproperty[j].fun)(wc))) + nRet |= mask; + break; + } + } + } + } + + + return nRet; +} \ No newline at end of file diff --git a/blogs/2021-12-19/wctype_h/iswdigit.c b/blogs/2021-12-19/wctype_h/iswdigit.c new file mode 100644 index 00000000000..ff754fd2f75 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/iswdigit.c @@ -0,0 +1,56 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + iswdigit.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#define _CTYPE_DISABLE_MACROS +#include + +#include +#include <_wctype.h> + +extern char _cdeChkIsWxTbl(ISWX_TRUTH_TABLE* pIswxTbl, wint_t c); + +extern ISWX_TRUTH_TABLE iswdigit_dflt_tbl[]; + +/** Brief description of the function’s purpose. + +Synopsis + #include + int iswdigit(wint_t wc); +Description + The iswdigit function tests for any wide character that corresponds to a decimal-digit + character (as defined in 5.2.1). + + @param[in] c character to test for DIGIT + + @retval ISDIGIT if upcase letter + + @retval 0 if not + +**/ +ISWX_TRUTH_TABLE* gpTBLiswdigit = iswdigit_dflt_tbl; + + +int iswdigit(wint_t c) { + + return _DIGIT * _cdeChkIsWxTbl(gpTBLiswdigit, c); +} + + diff --git a/blogs/2021-12-19/wctype_h/iswgraph.c b/blogs/2021-12-19/wctype_h/iswgraph.c new file mode 100644 index 00000000000..8ab946e1160 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/iswgraph.c @@ -0,0 +1,48 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + iswgraph.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#define _CTYPE_DISABLE_MACROS +#include + +/** Brief description of the function’s purpose. + +Synopsis + #include + int iswgraph(wint_t wc); +Description + The iswgraph function tests for any wide character for which iswprint is true and + iswspace is false + + @param[in] c character to test for isgraph + + @retval _ALPHA | ISDIGIT | ISPUNCT if matching letter + + @retval 0 if not + +**/ +int iswgraph(wint_t c) { + + int nRet0 = 0; + + nRet0 = iswalnum(c) | iswpunct(c); + + return nRet0; +} diff --git a/blogs/2021-12-19/wctype_h/iswlower.c b/blogs/2021-12-19/wctype_h/iswlower.c new file mode 100644 index 00000000000..8756eada854 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/iswlower.c @@ -0,0 +1,53 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + iswlower.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#define _CTYPE_DISABLE_MACROS +#include + +#include +#include <_wctype.h> + +extern char _cdeChkIsWxTbl(ISWX_TRUTH_TABLE* pIswxTbl, wint_t c); + +extern ISWX_TRUTH_TABLE iswlower_dflt_tbl[]; + +/** Brief description of the function’s purpose. + +Synopsis + #include + int iswlower(wint_t wc); +Description + The iswlower function tests for any wide character that corresponds to a lowercase + letter or is one of a locale-specific set of wide characters for which none of iswcntrl, + iswdigit, iswpunct, or iswspace is true. + + @param[in] c character to test for lowcase + + @retval ISLOWER if upcase letter + + @retval 0 if not + +**/ +ISWX_TRUTH_TABLE* gpTBLiswlower = iswlower_dflt_tbl; +int iswlower(wint_t c) { + + return _LOWER * _cdeChkIsWxTbl(gpTBLiswlower, c); +} diff --git a/blogs/2021-12-19/wctype_h/iswprint.c b/blogs/2021-12-19/wctype_h/iswprint.c new file mode 100644 index 00000000000..e691f5e9bcf --- /dev/null +++ b/blogs/2021-12-19/wctype_h/iswprint.c @@ -0,0 +1,53 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + iswprint.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#define _CTYPE_DISABLE_MACROS +#include + +/** Brief description of the function’s purpose. + +Synopsis + #include + int iswprint(wint_t wc); +Description + The iswprint function tests for any printing wide character. + + @param[in] c character to test for isprint + + @retval _ALPHA | ISDIGIT | ISPUNCT if matching letter + + @retval 0 if not + +**/ +int iswprint(wint_t c) { + + int nRet0 = 0, nRet1 = 0; + + if (c != '\t') { + nRet0 = iswgraph(c); + + if (0 == nRet0) + nRet1 = iswblank(c); + + } + return nRet0 | nRet1; + +} \ No newline at end of file diff --git a/blogs/2021-12-19/wctype_h/iswpunct.c b/blogs/2021-12-19/wctype_h/iswpunct.c new file mode 100644 index 00000000000..49ef90bb126 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/iswpunct.c @@ -0,0 +1,53 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + iswpunct.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#define _CTYPE_DISABLE_MACROS +#include + +#include +#include <_wctype.h> + +extern char _cdeChkIsWxTbl(ISWX_TRUTH_TABLE* pIswxTbl, wint_t c); + +extern ISWX_TRUTH_TABLE iswpunct_dflt_tbl[]; + +/** Brief description of the function’s purpose. + +Synopsis + #include + int iswpunct(wint_t wc); +Description + The iswpunct function tests for any printing wide character that is one of a localespecific + set of punctuation wide characters for which neither iswspace nor iswalnum + is true. + +@param[in] c character to test for lowcase + +@retval ISLOWER if upcase letter + +@retval 0 if not + +**/ +ISWX_TRUTH_TABLE* gpTBLiswpunct = iswpunct_dflt_tbl; +int iswpunct(wint_t c) { + + return _PUNCT * _cdeChkIsWxTbl(gpTBLiswpunct, c); +} diff --git a/blogs/2021-12-19/wctype_h/iswspace.c b/blogs/2021-12-19/wctype_h/iswspace.c new file mode 100644 index 00000000000..6aabc051fb7 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/iswspace.c @@ -0,0 +1,54 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + iswspace.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#define _CTYPE_DISABLE_MACROS +#include + +#include +#include <_wctype.h> + +extern char _cdeChkIsWxTbl(ISWX_TRUTH_TABLE* pIswxTbl, wint_t c); + +extern ISWX_TRUTH_TABLE iswspace_dflt_tbl[]; + +/** Brief description of the function’s purpose. + +Synopsis + #include + int iswspace(wint_t wc); +Description + The iswspace function tests for any wide character that corresponds to a locale-specific + set of white-space wide characters for which none of iswalnum, iswgraph, or + iswpunct is true. + + +@param[in] c character to test + +@retval _SPACE if upcase letter + +@retval 0 if not + +**/ +ISWX_TRUTH_TABLE* gpTBLiswspace = iswspace_dflt_tbl; +int iswspace(wint_t c) { + + return _SPACE * _cdeChkIsWxTbl(gpTBLiswspace, c); +} diff --git a/blogs/2021-12-19/wctype_h/iswupper.c b/blogs/2021-12-19/wctype_h/iswupper.c new file mode 100644 index 00000000000..d194b3c51f5 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/iswupper.c @@ -0,0 +1,53 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + iswupper.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#define _CTYPE_DISABLE_MACROS +#include + +#include +#include <_wctype.h> + +extern char _cdeChkIsWxTbl(ISWX_TRUTH_TABLE* pIswxTbl, wint_t c); + +extern ISWX_TRUTH_TABLE iswupper_dflt_tbl[]; + +/** Brief description of the function’s purpose. + +Synopsis + #include + int iswupper(wint_t wc); +Description + The iswupper function tests for any wide character that corresponds to an uppercase + letter or is one of a locale-specific set of wide characters for which none of iswcntrl, + iswdigit, iswpunct, or iswspace is true + +@param[in] c character to test + +@retval _UPPER if upcase letter + +@retval 0 if not + +**/ +ISWX_TRUTH_TABLE* gpTBLiswupper = iswupper_dflt_tbl; +int iswupper(wint_t c) { + + return _UPPER * _cdeChkIsWxTbl(gpTBLiswupper, c); +} diff --git a/blogs/2021-12-19/wctype_h/iswxdigit.c b/blogs/2021-12-19/wctype_h/iswxdigit.c new file mode 100644 index 00000000000..5f4f9e18696 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/iswxdigit.c @@ -0,0 +1,53 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + iswxdigit.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#define _CTYPE_DISABLE_MACROS +#include + +#include +#include <_wctype.h> + +extern char _cdeChkIsWxTbl(ISWX_TRUTH_TABLE* pIswxTbl, wint_t c); + +extern ISWX_TRUTH_TABLE iswxdigit_dflt_tbl[]; + +/** Brief description of the function’s purpose. + +Synopsis + #include + int iswxdigit(wint_t wc); +Description + The iswxdigit function tests for any wide character that corresponds to a + hexadecimal-digit character. + + +@param[in] c character to test + +@retval _HEX if upcase letter + +@retval 0 if not + +**/ +ISWX_TRUTH_TABLE* gpTBLiswxdigit = iswxdigit_dflt_tbl; +int iswxdigit(wint_t c) { + + return _HEX * _cdeChkIsWxTbl(gpTBLiswxdigit, c); +} diff --git a/blogs/2021-12-19/wctype_h/towctrans.c b/blogs/2021-12-19/wctype_h/towctrans.c new file mode 100644 index 00000000000..401711bad8d --- /dev/null +++ b/blogs/2021-12-19/wctype_h/towctrans.c @@ -0,0 +1,56 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + towctrans.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#include + +#include +#include <_wctype.h> + +/** Brief description of the function’s purpose. + +Synopsis + #include + wint_t towctrans(wint_t wc, wctrans_t desc); +Description + The towctrans function maps the wide character wc using the mapping described by + desc. The current setting of the LC_CTYPE category shall be the same as during the call + to wctrans that returned the value desc. + Each of the following expressions behaves the same as the call to the wide character case + mapping function (7.25.3.1) in the comment that follows the expression: + + towctrans(wc, wctrans("tolower")) // towlower(wc) + towctrans(wc, wctrans("toupper")) // towupper(wc) + +Returns + The towctrans function returns the mapped value of wc using the mapping described + by desc. + +@param[in] c character to test + +@retval _UPPER if upcase letter + +@retval 0 if not + +**/ +wint_t towctrans(wint_t c, wctrans_t value) { + + return value == _UPPER ? towupper(c) : towlower(c); +} diff --git a/blogs/2021-12-19/wctype_h/towlower.c b/blogs/2021-12-19/wctype_h/towlower.c new file mode 100644 index 00000000000..03acb15fcb0 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/towlower.c @@ -0,0 +1,48 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + towlower.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#include + +/** Brief description of the function’s purpose. + +Synopsis + #include + wint_t towlower(wint_t wc); +Description + The towlower function converts an uppercase letter to a corresponding lowercase letter. +Returns + If the argument is a wide character for which iswupper is true and there are one or + more corresponding wide characters, as specified by the current locale, for which + iswlower is true, the towlower function returns one of the corresponding wide + characters (always the same one for any giv en locale); otherwise, the argument is + returned unchanged. + + @param[in] c character to convert + + @retval converted c if convertable + + @retval unchanged c + +**/ +wint_t towlower(wint_t c/*@parm c to be converted to lower case*/) +{ + return c >= 'A' && c <= 'Z' ? 'a' + c - 'A' : c; +} diff --git a/blogs/2021-12-19/wctype_h/towupper.c b/blogs/2021-12-19/wctype_h/towupper.c new file mode 100644 index 00000000000..57de5efb0a8 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/towupper.c @@ -0,0 +1,48 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + towupper.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#include + +/** Brief description of the function’s purpose. + +Synopsis + #include + wint_t towupper(wint_t wc); +Description + The towupper function converts a lowercase letter to a corresponding uppercase letter. +Returns + If the argument is a wide character for which iswlower is true and there are one or + more corresponding wide characters, as specified by the current locale, for which + iswupper is true, the towupper function returns one of the corresponding wide + characters (always the same one for any giv en locale); otherwise, the argument is + returned unchanged. + + @param[in] c character to convert + + @retval converted c if convertable + + @retval 0 if not + +**/ +wint_t towupper(wint_t c/*@parm c to be case converted*/) +{ + return c >= 'a' && c <= 'z' ? 'A' + c - 'a' : c; +} diff --git a/blogs/2021-12-19/wctype_h/wctrans.c b/blogs/2021-12-19/wctype_h/wctrans.c new file mode 100644 index 00000000000..6491ed84395 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/wctrans.c @@ -0,0 +1,61 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + wctrans.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#include + +#include +#include +#include <_wctype.h> + +/** Brief description of the function’s purpose. + +Synopsis + #include + wctrans_t wctrans(const char *property); +Description + The wctrans function constructs a value with type wctrans_t that describes a + mapping between wide characters identified by the string argument property. + The strings listed in the description of the towctrans function shall be valid in all + locales as property arguments to the wctrans function. +Returns + Ifproperty identifies a valid mapping of wide characters according to the LC_CTYPE + category of the current locale, the wctrans function returns a nonzero value that is valid + as the second argument to the towctrans function; otherwise, it returns zero. + +@param[in] c character to test for lowcase + +@retval _UPPER on "toupper" / _LOWER on "tolower" + +@retval 0 otherwise + +**/ +wctrans_t wctrans(const char* name) { + + wctrans_t nRet = 0; + + if (0 == strcmp(name, "toupper")) + nRet = _UPPER; + else + if (0 == strcmp(name, "tolower")) + nRet = _LOWER; + + return nRet; +} diff --git a/blogs/2021-12-19/wctype_h/wctype.c b/blogs/2021-12-19/wctype_h/wctype.c new file mode 100644 index 00000000000..d7fd26aaae2 --- /dev/null +++ b/blogs/2021-12-19/wctype_h/wctype.c @@ -0,0 +1,68 @@ +/*++ + + toro C Library + https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library + + Copyright (c) 2017-2021, Kilian Kegel. All rights reserved. + SPDX-License-Identifier: GNU General Public License v3.0 + +Module Name: + + wctype.c + +Abstract: + + Implementation of the Standard C function. + +Author: + + Kilian Kegel + +--*/ +#include + +#include +#include <_wctype.h> +#include + +#define ELC(x)/*element count*/ (sizeof(x) / sizeof(x[0])) +extern WCPROPERTY _wcproperty[]; + +/** Brief description of the function’s purpose. + +Synopsis + #include + wctype_t wctype(const char *property); +Description + The wctype function constructs a value with type wctype_t that describes a class of + wide characters identified by the string argument property. + + The strings listed in the description of the iswctype function shall be valid in all + locales as property arguments to the wctype function. +Returns + If property identifies a valid class of wide characters according to the LC_CTYPE + category of the current locale, the wctype function returns a nonzero value that is valid + as the second argument to the iswctype function; otherwise, it returns zero. + +@param[in] const char *property -> "alpha","alnum","blank","cntrl","digit","graph","lower","print","punct","space","upper","xdigit" + +@retval non zero on success + +@retval 0 if not + +**/ +wint_t wctype(const char* property) { + wint_t nRet = 0; + int i = -1; + + if (NULL != property) { + while (NULL != _wcproperty[++i].szProperty) { + if (0 == strcmp(property, _wcproperty[i].szProperty)) { + nRet = _wcproperty[i].type; + break; + } + } + } + + return nRet; +} \ No newline at end of file diff --git a/blogs/2022-01-16/README.md b/blogs/2022-01-16/README.md new file mode 100644 index 00000000000..4a656062b8d --- /dev/null +++ b/blogs/2022-01-16/README.md @@ -0,0 +1,216 @@ +### CdePkgBlog 2022-01-16 +# Introduction of the ACPICA port to UEFI +![LOGO](https://github.com/KilianKegel/Visual-ACPICA-for-UEFI-Shell/blob/main/LOGO.PNG) +### Table of content +* [Abstract](README.md#abstract) +* [Introduction](README.md#Introduction) + * [introductory email](https://edk2.groups.io/g/devel/message/85720?p=%2C%2C%2C20%2C0%2C0%2C0%3A%3ACreated%2C%2CCdePkgBlog%2C20%2C2%2C0%2C88470049) + * [introductory videos](README.md#introductory-videos) +* [ACPICA](README.md#acpica--acpi-component-architecture) + * [Original project sourcecode](README.md#original-project-sourcecode) + * [Modified project sourcecode](README.md#modified-project-sourcecode) + * [```aslmain.c```](README.md#aslmainc) + * [```apmain.c```](README.md#apmainc) + * [```evglock.c```](README.md#evglockc) + * [```acwin.h```](README.md#acwinh) + * [```oswindir.c```](README.md#oswindirc) + * [```oswintbl.c```](README.md#oswintblc) + * [```oswinxf.c```](README.md#oswinxfc) +* [Win324UEFI](README.md#win324uefi) +* [toro-C-Library](README.md#toro-c-library) +* [Starting Visual Studio 2022](README.md#starting-visual-studio-2022) + * [Setup the buildenvironment](README.md#setup-the-buildenvironment) + * [Build the solution in Visual Studio](README.md#build-the-solution-in-visual-studio) +* [Coming up soon](README.md#coming-up-soon) + +## Abstract + +Demonstration on how to transform existing Standard C software projects to run in the UEFI Shell +using the latest development environment from Microsoft and the *open source*, *monolithic*, *multi-target* +[**toro C Library**](https://github.com/KilianKegel/toro-C-Library#toro-c-library-formerly-known-as-torito-c-library) +[1](footnotes/footnote-1.md) + +## Introduction + +"The ACPI Component Architecture (ACPICA) project provides an operating system (OS)-independent reference +implementation of the Advanced Configuration and Power Interface Specification (ACPI). +**It can be easily adapted to execute under any host OS.**" https://acpica.org/ + +This blog will demonstrate how surprisingly easy the port to the UEFI Shell is +when a *Standard C API* is available.[2](footnotes/footnote-2.md) + +This task was suggested by @ajfish and @jljusten at +tianocore / tianocore.github.io: +https://github.com/tianocore/tianocore.github.io/wiki/Tasks#port-acpi-ca-to-a-shell-application. + +The tools provided by the ACPICA are really useful during the development process of PC-platforms. +The extraction, comparison and disassembly of binary ACPI tables can be done easily directly +on the target. + +The "ACPI"-subcomponent on a particular platform, early in the development process - before a real OS is +able to start and run *RWEVERYTHING* - is suddenly much more tangible. + +A very common chicken/egg problem while engineering for UEFI platforms is, that analysis tools exclusively run +on "real" operating system — and said OS fails to boot due to precisely the problem that needs to be analysed. + +While UEFI Shell mostly runs in an early development stage of a board, those analysis tools +are regrettably not available for UEFI Shell. That is also true for *GPIO*-tools. + +### introductory videos +* build *Visual-ACPICA-for-UEFI-Shell*: https://www.youtube.com/watch?v=POfSJQXi2aM +* run *ACPIDUMP.efi* and *ASLCOMPILER.efi*: https://www.youtube.com/watch?v=oA1GA95WrF0 + +# ACPICA — ACPI Component Architecture +## Original project sourcecode +The ACPICA reference implementation is available here: https://acpica.org/source
+This port is based on the version https://acpica.org/node/196 from September 2021. + +The x86-Windows-version is only available for an old Visual Studio version (2017) +and regrettably only for x86-32 instruction set. + +The shift to x86-64 instruction set produces some warnings during compilation process +that I left open. + +A datatype ```long``` of 32Bit-size in x86-64 mode necessarily had to be fixed. + +## Modified project sourcecode +Only the Microsoft-specific project files have been transferred and modified to the +new "*VisualStudio2022 solution*" **AcpiComponents.sln**. + +From the about 400 orignal .C and .H files that belong to the project, only 7 +files need to be modified: + +![Overall](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2022-01-16/pictures/overall.png) + +All source code modifications have been encapsulated in the ```VISUAL_ACPICA_FOR_UEFI``` +build switch. + +Additionally a couple of Windows functions need to be rewritten for UEFI usage. +The library is called [Win324UEFI.lib](README.md#win324uefi) + +### [aslmain.c](https://github.com/KilianKegel/Visual-ACPICA-for-UEFI-Shell/blob/main/acpica-win-20210930-source/compiler/aslmain.c) +```aslmain.c``` is the master file for the *AslCompiler*. To build successfully +it needs ```EFI_SYSTEM_TABLE``` and ```EFI_HANDLE``` to initialize global variables. +```EFI_SYSTEM_TABLE``` and ```EFI_HANDLE``` have been passed via ```argv[-1]``` and ```argv[-2]```. + +![aslmain.c](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2022-01-16/pictures/aslmain.c.png) + + +### [apmain.c](https://github.com/KilianKegel/Visual-ACPICA-for-UEFI-Shell/blob/main/acpica-win-20210930-source/tools/acpidump/apmain.c) +```apmain.c``` is the master file for the *AcpiDump* utility. To build successfully +it needs ```EFI_SYSTEM_TABLE``` and ```EFI_HANDLE``` to initialize global variables. +```EFI_SYSTEM_TABLE``` and ```EFI_HANDLE``` have been passed via ```argv[-1]``` and ```argv[-2]```. + +*AcpiDump* really needs UEFI API access, since it needs to find the ACPI tables in the BIOS Flash +using the rewritten Windows-API-functions ```GetSystemFormwareTables()``` and ```EnumSystemFirmwareTables()```. +This functions were provided by the [Win324UEFI.lib](https://github.com/KilianKegel/Win324UEFI). + +![apmain.c](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2022-01-16/pictures/apmain.c.png) + +### [evglock.c](https://github.com/KilianKegel/Visual-ACPICA-for-UEFI-Shell/blob/main/acpica-win-20210930-source/components/events/evglock.c) +```evglock.c``` provides the Global Lock support. The functions ```AcpiAcquireGlobalLock()``` +and ```AcpiReleaseGlobalLock()``` need to be rewritten from inline assembly language to +Microsoft C intrinsics, because for 64Bit code generator inline-assembler is not supported anymore. + +![evglock.c](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2022-01-16/pictures/evglock.c.png) + +### [acwin.h](https://github.com/KilianKegel/Visual-ACPICA-for-UEFI-Shell/blob/main/acpica-win-20210930-source/include/platform/acwin.h) +For the same reasons the macros in ```acwin.h```have to be adjusted. + +![acwin.h](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2022-01-16/pictures/acwin.h.png) + +### [oswindir.c](https://github.com/KilianKegel/Visual-ACPICA-for-UEFI-Shell/blob/main/acpica-win-20210930-source/os_specific/service_layers/oswindir.c) +The datatype ```long``` has in 64Bit/32Bit +* Microsoft Compiler: same size +* GNU Compiler different size + +So ```FileHandle```would be 32Bit in size when building for 64Bit — thats wrong. + +![oswindir.c](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2022-01-16/pictures/oswindir.c.png) + +### [oswintbl.c](https://github.com/KilianKegel/Visual-ACPICA-for-UEFI-Shell/blob/main/acpica-win-20210930-source/os_specific/service_layers/oswintbl.c) + +* [```EnumSystemFirmwareTables4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/EnumSystemFirmwareTables.c) +* [```GetSystemFirmwareTable4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/GetSystemFirmwareTable.c) + +with slightly different parameters instead its original Windows counter parts. + +To add ```4UEFI```-suffix was a workaround to avoid a conflict with calling conventions of the original +Microsoft function definitions in the header files. + +![oswintbl.c](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2022-01-16/pictures/oswintbl.c.png) + +### [oswinxf.c](https://github.com/KilianKegel/Visual-ACPICA-for-UEFI-Shell/blob/main/acpica-win-20210930-source/os_specific/service_layers/oswinxf.c) +* [```QueryPerformanceCounter4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/QueryPerformanceCounter.c) +* [```QueryPerformanceFrequency4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/QueryPerformanceFrequency.c) +* [```GetTickCount644UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/GetTickCount64.c) +* [```Sleep4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/Sleep.c) +* [```IsBadReadPtr4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/IsBadReadPtr.c) +* [```IsBadWritePtr4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/IsBadWritePtr.c) + +Reimplementation of the original Windows functions. + +To add ```4UEFI```-suffix was a workaround to avoid a conflict with calling conventions of the original +Microsoft function definitions in the header files. + +![oswinxf.c](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2022-01-16/pictures/oswinxf.c.png) + +# [Win324UEFI](https://github.com/KilianKegel/Win324UEFI) +**Win324UEFI** is a library that supplies *Win32 API* functions for UEFI Shell usage. +The library is updated with new functions on demand only. It is not planned to implement +a full subset of a particular *Win32 API interface* completely. + +Currently the library provides the functions listed below: +* [```EnumSystemFirmwareTables4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/EnumSystemFirmwareTables.c): https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-enumsystemfirmwaretables +* [```GetSystemFirmwareTable4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/GetSystemFirmwareTable.c): https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemfirmwaretable +* [```QueryPerformanceCounter4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/QueryPerformanceCounter.c): https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter +* [```QueryPerformanceFrequency4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/QueryPerformanceFrequency.c): https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancefrequency +* [```GetTickCount644UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/GetTickCount64.c): https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-gettickcount64 +* [```Sleep4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/Sleep.c): https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleep +* [```IsBadReadPtr4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/IsBadReadPtr.c): https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-isbadreadptr +* [```IsBadWritePtr4UEFI()```](https://github.com/KilianKegel/Win324UEFI/blob/main/IsBadWritePtr.c): https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-isbadwriteptr + +# [toro-C-Library](https://github.com/KilianKegel/toro-C-Library) +The original **toro-C-Library** source code is included in the project. + +This is for informational purpose only. + +Currently **toro-C-Library** has these functions implemented:
+https://github.com/KilianKegel/toro-C-Library#implementation-status + +The library can also be used for UEFI POST drivers and to build executables for Windows. + +# Starting Visual Studio 2022 +## Setup the buildenvironment +1. install FLEX and BISON that are required for the *AslCompiler*:
+ https://acpica.org/downloads/windows-source +2. [install Visual Studio 2022](https://github.com/KilianKegel/HowTo-setup-an-UEFI-Development-PC#2-install-visual-studio-2022) + +## Build the solution in Visual Studio +Once the [Visual-ACPICA-for-UEFI-Shell](https://github.com/KilianKegel/Visual-ACPICA-for-UEFI-Shell/tree/dc74325f55b02253165fb64e08d64271c99ddfcf) +repository is cloned to the build PC, just double click ```AcpiComponents.sln```. This will start Visual Studio 2022. + +Just press 'F7' to build the entire solution including the **toro-C-Library** and the **Win324UEFI** +projects. + +The .EFI files appear in the ```x64\UEFIShell``` folder. + + +## Coming up soon... +2021-11-28:
+* Using UEFI- and Standard-C-API in shell applications
+* Creating MSDOS tools.
+2021-12-12:
+* Adopting open source Visual-Studio projects to UEFI
+* Introduction of the ACPCIA port to UEFI
+ +**2021-12-19:** +* Redfish on CdePkg
+ +**2022-01-16:** +* Adopting open source Visual-Studio projects to UEFI
+* Introduction of the ACPICA port to UEFI
+ +**2022-01-30:** +* Introduction of how to calibrate a TSC-based software timer - on IBM-AT compatible UEFI platforms + diff --git a/blogs/2022-01-16/Visual-ACPICA-for-UEFI-Shell b/blogs/2022-01-16/Visual-ACPICA-for-UEFI-Shell new file mode 160000 index 00000000000..220f72e8574 --- /dev/null +++ b/blogs/2022-01-16/Visual-ACPICA-for-UEFI-Shell @@ -0,0 +1 @@ +Subproject commit 220f72e85748c30ef2073fb18bc1482502997978 diff --git a/blogs/2022-01-16/footnotes/footnote-1.md b/blogs/2022-01-16/footnotes/footnote-1.md new file mode 100644 index 00000000000..7bd07f90328 --- /dev/null +++ b/blogs/2022-01-16/footnotes/footnote-1.md @@ -0,0 +1,5 @@ +NOTE: All statements regarding implementation specific details of **toro C Library** are always strictly focused on +my observations of Microsoft C Library, running "C" locale, at UTC timezone. Referring to Standard/ANSI C might be a +Microsoft specific implementation of the specification, but I always give my best to double-check the statements on GCC x64. In critical cases +also old Borland, Watcom and Digital Mars C compiler and library were queried. **toro C Library** is engineered -- not "scientifized". +This is also true for all upcoming CdePkgBlogs. diff --git a/blogs/2022-01-16/footnotes/footnote-2.md b/blogs/2022-01-16/footnotes/footnote-2.md new file mode 100644 index 00000000000..d5b93f25558 --- /dev/null +++ b/blogs/2022-01-16/footnotes/footnote-2.md @@ -0,0 +1,2 @@ +In contrast to https://github.com/tianocore/edk2/tree/master/ShellPkg/Library/UefiShellAcpiViewCommandLib +that is a complete reimplementation based on *UEFI Shell programming model*. diff --git a/blogs/2022-01-16/pictures/acwin.h.png b/blogs/2022-01-16/pictures/acwin.h.png new file mode 100644 index 00000000000..6bb0f68c8f0 Binary files /dev/null and b/blogs/2022-01-16/pictures/acwin.h.png differ diff --git a/blogs/2022-01-16/pictures/apmain.c.png b/blogs/2022-01-16/pictures/apmain.c.png new file mode 100644 index 00000000000..b6c2dca2568 Binary files /dev/null and b/blogs/2022-01-16/pictures/apmain.c.png differ diff --git a/blogs/2022-01-16/pictures/aslmain.c.png b/blogs/2022-01-16/pictures/aslmain.c.png new file mode 100644 index 00000000000..93366df80b5 Binary files /dev/null and b/blogs/2022-01-16/pictures/aslmain.c.png differ diff --git a/blogs/2022-01-16/pictures/evglock.c.png b/blogs/2022-01-16/pictures/evglock.c.png new file mode 100644 index 00000000000..58b906ffd26 Binary files /dev/null and b/blogs/2022-01-16/pictures/evglock.c.png differ diff --git a/blogs/2022-01-16/pictures/oswindir.c.png b/blogs/2022-01-16/pictures/oswindir.c.png new file mode 100644 index 00000000000..6eae58a9a1e Binary files /dev/null and b/blogs/2022-01-16/pictures/oswindir.c.png differ diff --git a/blogs/2022-01-16/pictures/oswintbl.c.png b/blogs/2022-01-16/pictures/oswintbl.c.png new file mode 100644 index 00000000000..c9847e31ee3 Binary files /dev/null and b/blogs/2022-01-16/pictures/oswintbl.c.png differ diff --git a/blogs/2022-01-16/pictures/oswinxf.c.png b/blogs/2022-01-16/pictures/oswinxf.c.png new file mode 100644 index 00000000000..54df24fae46 Binary files /dev/null and b/blogs/2022-01-16/pictures/oswinxf.c.png differ diff --git a/blogs/2022-01-16/pictures/overall.png b/blogs/2022-01-16/pictures/overall.png new file mode 100644 index 00000000000..e501b93b872 Binary files /dev/null and b/blogs/2022-01-16/pictures/overall.png differ diff --git a/blogs/README.md b/blogs/README.md new file mode 100644 index 00000000000..cc6d36e6f27 --- /dev/null +++ b/blogs/README.md @@ -0,0 +1,6 @@ + +## CdePkg blog at UEFI **tianocore** +[![Repo name](https://github-readme-stats.vercel.app/api/pin/?username=KilianKegel&repo=Introduction-of-the-ACPICA-port-to-UEFI)](https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2022-01-16#introduction-of-the-acpica-port-to-uefi) +[![Repo name](https://github-readme-stats.vercel.app/api/pin/?username=KilianKegel&repo=RedFish-on-CdePkg)](https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2021-12-19#redfish-on-cdepkg) +[![Repo name](https://github-readme-stats.vercel.app/api/pin/?username=KilianKegel&repo=Using-UEFI--and-Standard-C-API-in-shell-applications-creating-MSDOS-Tools-for-UEFI)](https://github.com/tianocore/edk2-staging/tree/CdePkg/blogs/2021-11-28#using-uefi--and-standard-c-api-in-shell-applications-creating-msdos-tools-for-uefi) +[![Repo name](https://github-readme-stats.vercel.app/api/pin/?username=KilianKegel&repo=my-legacy-toolbox)](https://github.com/tianocore/edk2-staging/blob/CdePkg/blogs/2021-11-14/README.md#my-legacy-toolbox) diff --git a/dbgemu.bat b/dbgemu.bat new file mode 100644 index 00000000000..172c994af0e --- /dev/null +++ b/dbgemu.bat @@ -0,0 +1,8 @@ +@echo off +rem +rem Copyright (c) 2019, Kilian Kegel. All rights reserved.
+rem SPDX-License-Identifier: BSD-2-Clause-Patent +rem +pushd %WORKSPACE%\Build\EmulatorIA32\DEBUG_VS2015x86\IA32 +start %WORKSPACE%\Build\EmulatorIA32\DEBUG_VS2015x86\IA32\WinHost.exe /debug +popd diff --git a/edk2 b/edk2 new file mode 160000 index 00000000000..bb1bba3d776 --- /dev/null +++ b/edk2 @@ -0,0 +1 @@ +Subproject commit bb1bba3d776733c41dbfa2d1dc0fe234819a79f2 diff --git a/edk2-non-osi b/edk2-non-osi new file mode 160000 index 00000000000..eef5e03e52f --- /dev/null +++ b/edk2-non-osi @@ -0,0 +1 @@ +Subproject commit eef5e03e52f41492ff7af1a7985bc5eda8d7a448 diff --git a/edk2-platforms b/edk2-platforms new file mode 160000 index 00000000000..818e8b7beb5 --- /dev/null +++ b/edk2-platforms @@ -0,0 +1 @@ +Subproject commit 818e8b7beb514d3ddbe33820ea130591d109c45f diff --git a/implemented.md b/implemented.md new file mode 100644 index 00000000000..d6edc41a9e8 --- /dev/null +++ b/implemented.md @@ -0,0 +1,216 @@ +NOTE: +* "TCL" is the [torito-C-Library](https://github.com/KilianKegel/torito-C-Library) +* "a" -> approved +* "n/a" -> not approved +## Validation Status + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Diagnostics < assert.h > TCL DXE PEI
void _wassert (const wchar_t *,const wchar_t *,unsigned)C90, MSFT implementation for assert macroaaa
Character handling < ctype.h >TCLDXE PEI
int isalnum(int) C90, is implemented aaa
int isalpha(int) C90, is implemented aaa
int iscntrl(int) C90, is implemented aaa
int isdigit(int) C90, is implemented aaa
int isgraph(int) C90, is implemented aaa
int islower(int) C90, is implemented aaa
int isprint(int) C90, is implemented aaa
int ispunct(int) C90, is implemented aaa
int isspace(int) C90, is implemented aaa
int isupper(int) C90, is implemented aaa
int isxdigit(int) C90, is implemented aaa
int tolower(int) C90, is implemented aaa
int toupper(int) C90, is implemented aaa
Errors < errno.h >TCLDXE PEI
int *_errno(void)C90, MSFT implementation for errno macro a
Localization < locale.h >TCLDXE PEI
struct lconv *localeconv(void) C90, is implemented (C-locale) aaa
char *setlocale(int category, const char *locale) C90, is implemented (C-locale)aaa
Nonlocal jumps < setjmp.h >TCLDXE PEI
int setjmp(jmp_buf env) C90, _setjmp is implementedaaa
void longjmp(jmp_buf env, int val) C90, is implemented aaa
Signal handling < signal.h >TCLDXE PEI
void (*signal(int sig, void (*func)(int)))(int) C90, is implemented a
int raise(int sig) C90, is implemented a
Input/output < stdio.h >TCLDXE PEI
int remove(const char *filename) C90, is implemented a
int rename(const char *old, const char *new) C90, is implemented a
FILE *tmpfile(void) C90, is implemented a
char *tmpnam(char *s) C90, is implemented aaa
int fclose(FILE *stream) C90, is implemented a
int fflush(FILE *stream) C90, is implementeda
FILE *fopen(const char * filename,const char * mode) C90, is implementeda
FILE *freopen(const char * filename,const char * mode,FILE * stream) C90, is implementeda
void setbuf(FILE * stream,char * buf) C90, is implementeda
int setvbuf(FILE * stream,char * buf,int mode, size_t size) C90, is implementeda
int fprintf(FILE * stream,const char * format, ...) C90, is implementeda
int fscanf(FILE * stream,const char * format, ...) C90, is implementeda
int printf(const char * format, ...) C90, is implementedaaa
int scanf(const char * format, ...) C90, is implementeda
int snprintf(char * s, size_t n,const char * format, ...) C99, is implementedaaa
int sprintf(char * s,const char * format, ...) C90, is implementedaaa
int sscanf(const char * s,const char * format, ...) C90, is implementedaaa
int vfprintf(FILE * stream,const char * format, va_list arg) C90, is implementeda
int vprintf(const char * format, va_list arg) C90, is implementedaaa
int vsprintf(char * s,const char * format, va_list arg) C90, is implementedaaa
int vfscanf(FILE * stream,const char * format, va_list arg) C99, is implementeda
int vscanf(const char * format, va_list arg) C99, is implementeda
int vsnprintf(char * s, size_t n,const char * format, va_list arg) C99, is implementedaaa
int vsscanf(const char * s,const char * format, va_list arg) C99, is implementedaaa
int fgetc(FILE *stream) C90, is implementeda
char *fgets(char * s, int n,FILE * stream) C90, is implementeda
int fputc(int c, FILE *stream) C90, is implementeda
int fputs(const char * s,FILE * stream) C90, is implementeda
int getc(FILE *stream) C90, is implementeda
int getchar(void) C90, is implementeda
char *gets(char *s) C90, is implementeda
int putc(int c, FILE *stream) C90, is implementeda
int putchar(int c) C90, is implementeda
int puts(const char *s) C90, is implementeda
int ungetc(int c, FILE *stream) C90, is implementeda
size_t fread(void * ptr,size_t size, size_t nmemb,FILE * stream) C90, is implementeda
size_t fwrite(const void * ptr,size_t size, size_t nmemb,FILE * stream) C90, is implementeda
int fgetpos(FILE * stream,fpos_t * pos) C90, is implementeda
int fseek(FILE *stream, long int offset, int whence) C90, is implementeda
int fsetpos(FILE *stream, const fpos_t *pos) C90, is implementeda
long int ftell(FILE *stream) C90, is implementeda
void rewind(FILE *stream) C90, is implementeda
void clearerr(FILE *stream) C90, is implementeda
int feof(FILE *stream) C90, is implementeda
int ferror(FILE *stream) C90, is implementeda
void perror(const char *s) C90, is implementeda
General utilities < stdlib.h >TCLDXE PEI
double atof(const char *nptr)C90, is not yet implemented
int atoi(const char *nptr)C90, is implementedaaa
long int atol(const char *nptr)C90, is implementedaaa
double strtod(const char * nptr,char ** endptr)C90, is not yet implemented
long int strtol(const char * nptr,char ** endptr, int base)C90, is implementedaaa
unsigned long int strtoul(const char * nptr,char ** endptr, int base)C90, is implementedaaa
int rand(void)C90, is implementedaaa
void srand(unsigned int seed)C90, is implementedaaa
void *calloc(size_t nmemb, size_t size)C90, is implementedaaa
void free(void *ptr)C90, is implementedaaa
void *malloc(size_t size)C90, is implementedaaa
void *realloc(void *ptr, size_t size)C90, is implementedaaa
void abort(void)C90, is implementeda
int atexit(void (*func)(void))C90, is implementedaaa
void exit(int status)C90, is implementedaaa
char *getenv(const char *name)C90, is implementeda
int system(const char *string)C90, is implementeda
void *bsearch(const void *key, const void *base,size_t nmemb, size_t size,int (*compar)(const void *, const void *))C90, is not yet implemented
void qsort(void *base, size_t nmemb, size_t size,int (*compar)(const void *, const void *))C90, is implementedaaa
int abs(int j)C90, is implementedaaa
long int labs(long int j)C90, is implementedaaa
div_t div(int numer, int denom)C90, is implementedaaa
ldiv_t ldiv(long int numer, long int denom)C90, is implementedaaa
int mblen(const char *s, size_t n)C90, is not yet implemented
int mbtowc(wchar_t * pwc,const char * s, size_t n)C90, is not yet implemented
int wctomb(char *s, wchar_t wchar)C90, is not yet implemented
size_t mbstowcs(wchar_t * pwcs,const char * s, size_t n)C90, is not yet implemented
size_t wcstombs(char * s,const wchar_t * pwcs, size_t n)C90, is not yet implemented
String handling < string.h >TCLDXE PEI
void *memcpy(void * s1,const void * s2, size_t n)C90, is implementedaaa
void *memmove(void *s1, const void *s2, size_t n)C90, is implementedaaa
char *strcpy(char * s1,const char * s2)C90, is implementedaaa
char *strncpy(char * s1,const char * s2, size_t n)C90, is implementedaaa
char *strcat(char * s1,const char * s2)C90, is implementedaaa
char *strncat(char * s1,const char * s2, size_t n)C90, is implementedaaa
int memcmp(const void *s1, const void *s2, size_t n)C90, is implementedaaa
int strcmp(const char *s1, const char *s2)C90, is implementedaaa
int strcoll(const char *s1, const char *s2)C90, is not yet implemented
int strncmp(const char *s1, const char *s2, size_t n)C90, is implementedaaa
size_t strxfrm(char * s1,const char * s2, size_t n)C90, is not yet implemented
void *memchr(const void *s, int c, size_t n)C90, is implementedaaa
char *strchr(const char *s, int c)C90, is implementedaaa
size_t strcspn(const char *s1, const char *s2)C90, is implementedaaa
char *strpbrk(const char *s1, const char *s2)C90, is implementedaaa
char *strrchr(const char *s, int c)C90, is implementedaaa
size_t strspn(const char *s1, const char *s2)C90, is implementedaaa
char *strstr(const char *s1, const char *s2)C90, is implementedaaa
char *strtok(char * s1,const char * s2)C90, is implementedaaa
void *memset(void *s, int c, size_t n)C90, is implementedaaa
char *strerror(int errnum)C90, is implementedaaa
size_t strlen(const char *s)C90, is implementedaaa
Date and time < time.h >TCLDXE PEI
clock_t clock(void)C90, is implementedaaa
double difftime(time_t time1, time_t time0)C90, is implementedaaa
time_t mktime(struct tm *timeptr)C90, is implementedaaa
time_t time(time_t *timer)C90, is implementedaaa
char *asctime(const struct tm *timeptr)C90, is implementedaaa
char *ctime(const time_t *timer)C90, is implementedaaa
struct tm *gmtime(const time_t *timer)C90, is implementedaaa
struct tm *localtime(const time_t *timer)C90, function supports UTC onlyaaa
size_t strftime(char * s,size_t maxsize,const char * format,const struct tm * timeptr)C90, is implementedaaa
Extended multibyte/wide character utilities < wchar.h >TCLDXE PEI
int fwprintf(FILE * stream,const wchar_t * format, ...)C95, is not yet implemented
int fwscanf(FILE * stream,const wchar_t * format, ...)C95, is not yet implemented
int wprintf(const wchar_t * format, ...)C95, is implementedaaa
int wscanf(const wchar_t * format, ...)C95, is not yet implemented
int swprintf(wchar_t * s, size_t n,const wchar_t * format, ...)C95, is implementedaaa
int swscanf(const wchar_t * s,const wchar_t * format, ...)C95, is not yet implemented
int vfwprintf(FILE * stream,const wchar_t * format, va_list arg)C95, is not yet implemented
int vwprintf(const wchar_t * format,va_list arg)C95, is not yet implemented
int vswprintf(wchar_t * s, size_t n,const wchar_t * format, va_list arg)C95, is implementedaaa
wint_t fgetwc(FILE *stream)C95, is not yet implemented
wchar_t *fgetws(wchar_t * s, int n,FILE * stream)C95, is not yet implemented
wint_t fputwc(wchar_t c, FILE *stream)C95, is not yet implemented
int fputws(const wchar_t * s,FILE * stream)C95, is not yet implemented
wint_t getwc(FILE *stream)C95, is not yet implemented
wint_t getwchar(void)C95, is not yet implemented
wint_t putwc(wchar_t c, FILE *stream)C95, is not yet implemented
wint_t putwchar(wchar_t c)C95, is not yet implemented
wint_t ungetwc(wint_t c, FILE *stream)C95, is not yet implemented
int fwide(FILE *stream, int mode)C95, is not yet implemented
double wcstod(const wchar_t * nptr,wchar_t ** endptr)C95, is not yet implemented
long int wcstol(const wchar_t * nptr,wchar_t ** endptr, int base)C95, is not yet implemented
unsigned long int wcstoul(const wchar_t * nptr,wchar_t ** endptr, int base)C95, is not yet implemented
wchar_t *wcscpy(wchar_t * s1,const wchar_t * s2)C95, is implementedaaa
wchar_t *wcsncpy(wchar_t * s1,const wchar_t * s2, size_t n)C95, is implementedaaa
wchar_t *wcscat(wchar_t * s1,const wchar_t * s2)C95, is implementedaaa
wchar_t *wcsncat(wchar_t * s1,const wchar_t * s2, size_t n)C95, is implementedaaa
int wcscmp(const wchar_t *s1, const wchar_t *s2)C95, is implementedaaa
int wcscoll(const wchar_t *s1, const wchar_t *s2)C95, is not yet implemented
int wcsncmp(const wchar_t *s1, const wchar_t *s2,size_t n)C95, is implementedaaa
size_t wcsxfrm(wchar_t * s1,const wchar_t * s2, size_t n)C95, is not yet implemented
wchar_t *wcschr(const wchar_t *s, wchar_t c)C95, is implementedaaa
size_t wcscspn(const wchar_t *s1, const wchar_t *s2)C95, is implementedaaa
wchar_t *wcspbrk(const wchar_t *s1, const wchar_t *s2)C95, is implementedaaa
wchar_t *wcsrchr(const wchar_t *s, wchar_t c)C95, is implementedaaa
size_t wcsspn(const wchar_t *s1, const wchar_t *s2)C95, is implementedaaa
wchar_t *wcsstr(const wchar_t *s1, const wchar_t *s2)C95, is implementedaaa
wchar_t *wcstok(wchar_t * s1,const wchar_t * s2,wchar_t ** ptr)C95, is implementedaaa
size_t wcslen(const wchar_t *s)C95, is implementedaaa
wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n)C95, is not yet implemented
int wmemcmp(const wchar_t *s1, const wchar_t *s2,size_t n)C95, is implementedaaa
wchar_t *wmemcpy(wchar_t * s1,const wchar_t * s2, size_t n)C95, is implementedaaa
wchar_t *wmemmove(wchar_t *s1, const wchar_t *s2,size_t n)C95, is implementedaaa
wchar_t *wmemset(wchar_t *s, wchar_t c, size_t n)C95, is implementedaaa
size_t wcsftime(wchar_t * s, size_t maxsize,const wchar_t * format,const struct tm * timeptr)C95, is not yet implemented
wint_t btowc(int c)C95, is not yet implemented
int wctob(wint_t c)C95, is not yet implemented
int mbsinit(const mbstate_t *ps)C95, is not yet implemented
size_t mbrlen(const char * s, size_t n,mbstate_t * ps)C95, is not yet implemented
size_t mbrtowc(wchar_t * pwc,const char * s, size_t n,mbstate_t * ps)C95, is not yet implemented
size_t wcrtomb(char * s, wchar_t wc,mbstate_t * ps)C95, is not yet implemented
size_t mbsrtowcs(wchar_t * dst,const char ** src, size_t len,mbstate_t * ps)C95, is not yet implemented
size_t wcsrtombs(char * dst,const wchar_t ** src, size_t len,mbstate_t * ps)C95, is not yet implemented
Wide character classification and mapping utilities < wctype.h >TCLDXE PEI
int iswalnum(wint_t wc) C95, is implemented aaa
int iswalpha(wint_t wc) C95, is implemented aaa
int iswblank(wint_t wc) C99, is implemented aaa
int iswcntrl(wint_t wc) C95, is implemented aaa
int iswdigit(wint_t wc) C95, is implemented aaa
int iswgraph(wint_t wc) C95, is implemented aaa
int iswlower(wint_t wc) C95, is implemented aaa
int iswprint(wint_t wc) C95, is implemented aaa
int iswpunct(wint_t wc) C95, is implemented aaa
int iswspace(wint_t wc) C95, is implemented aaa
int iswupper(wint_t wc) C95, is implemented aaa
int iswxdigit(wint_t wc) C95, is implemented aaa
int iswctype(wint_t wc, wctype_t desc) C95, is implemented aaa
wctype_t wctype(const char *property) C95, is implemented aaa
wint_t towlower(wint_t wc)C95, is implemented aaa
wint_t towupper(wint_t wc)C95, is implemented aaa
wint_t towctrans(wint_t wc, wctrans_t desc)C95, is implemented aaa
wctrans_t wctrans(const char *property)C95, is implemented aaa
diff --git a/launch.bat b/launch.bat new file mode 100644 index 00000000000..a626e93d61c --- /dev/null +++ b/launch.bat @@ -0,0 +1,134 @@ +@echo off +rem +rem Copyright (c) 2019, Kilian Kegel. All rights reserved.
+rem SPDX-License-Identifier: BSD-2-Clause-Patent +rem + + +set path=%USERPROFILE%\appdata\Local\Programs\Python\Python37;%path% + +rem ####################################################################### +rem ### Check tools presence ############################################## +rem ####################################################################### +rem +rem WINDDK 3790.1830 installation check... +rem +rem if not exist c:\WINDDK\3790.1830\install.htm ( +rem echo ATTENTION: DDK 3790.1830 not installed +rem echo download from http://download.microsoft.com/download/9/0/f/90f019ac-8243-48d3-91cf-81fc4093ecfd/1830_usa_ddk.iso +rem ping 127.0.0.0 > nul +rem ) else ( +rem echo WINDDK 3790.1830 is installed +rem ) + +rem +rem VS2015 installation check... +rem + +if not exist "c:\Program Files (x86)\Microsoft Visual Studio 14.0\vc\bin\vcvars32.bat" ( + if not exist "C:\Program Files (x86)\Microsoft Visual Studio\Shared\14.0\VC\bin\vcvars32.bat" ( + echo ATTENTION: Visual Studio 2015 not installed + pause + goto EOF + ) else ( + echo VS2015 is installed + ) +) else ( + echo VS2015 is installed +) + +python --version > NUL 2>&1 +if errorlevel 1 ( + echo PYTHON is not installed. + echo Please install PYTHON from https://www.python.org/ftp/python/3.7.4/python-3.7.4-amd64.exe + pause + goto EOF +) else ( + python --version +) + +git.exe --version > NUL 2>&1 +if errorlevel 1 ( + echo GIT is not installed. + echo Please install GIT from https://github.com/git-for-windows/git/releases/download/v2.23.0.windows.1/Git-2.23.0-64-bit.exe + PAUSE + goto EOF +) else ( + git --version +) + +if not exist c:\ASL ( + echo Intel ASL compiler is not installed. + echo Please install Intel ASL compiler from https://acpica.org/sites/acpica/files/iasl-win-20160527.zip -OutFile download\iasl-win-20160527.zip to C:\ASL +) else ( + c:\asl\iasl.exe | find "Optimizing Compiler" +) + +rem ####################################################################### +rem ### local tools ####################################################### +rem ####################################################################### +if not exist openssl-1.0.2r-x64_86-win64 ( + powershell "& {[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri "https://indy.fulgan.com/SSL/openssl-1.0.2r-x64_86-win64.zip -OutFile openssl-1.0.2r-x64_86-win64.zip"}" + + if not exist openssl-1.0.2r-x64_86-win64.zip ( + rem ####################################################################### + rem ### if https://indy.fulgan.com/SSL/openssl-1.0.2r-x64_86-win64.zip not available + rem ####################################################################### + git clone https://github.com/KilianKegel/openSSLBinary.git + move openSSLBinary\openssl-1.0.2r-x64_86-win64.zip . + rd /s /q openSSLBinary + ) + powershell Expand-Archive openssl-1.0.2r-x64_86-win64.zip) +) +if not exist nasm-2.13.03 ( + powershell "& {[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri "https://www.nasm.us/pub/nasm/releasebuilds/2.13.03/win64/nasm-2.13.03-win64.zip -OutFile nasm-2.13.03-win64.zip"}" + powershell Expand-Archive nasm-2.13.03-win64.zip . +) + +rem ####################################################################### +rem ### EDK2 and EDK2-NON-OSI ############################################# +rem ####################################################################### +rem if not exist edk2 git clone --recursive https://github.com/tianocore/edk2.git edk2 +rem if not exist edk2-non-osi git clone --recursive https://github.com/tianocore/edk2-non-osi.git edk2-non-osi +rem if not exist edk2-platforms git clone --recursive https://github.com/tianocore/edk2-platforms.git edk2-platforms +rem if not exist CdeBinPkg git clone --recursive https://github.com/KilianKegel/CdeBinPkg.git CdeBinPkg +rem git submodule update --init --recursive +git submodule init + +rem ####################################################################### +rem ### set build environment ############################################# +rem ####################################################################### +rem +set WORKSPACE=%CD% +set PACKAGES_PATH=%WORKSPACE%\edk2 +set PACKAGES_PATH=%WORKSPACE%;%PACKAGES_PATH%; +set PACKAGES_PATH=%WORKSPACE%\edk2-platforms\Silicon\Intel;%PACKAGES_PATH%; +set PACKAGES_PATH=%WORKSPACE%\edk2-platforms\Platform\Intel;%PACKAGES_PATH%; +set PACKAGES_PATH=%WORKSPACE%\edk2-non-osi\Silicon\Intel;%PACKAGES_PATH%; +set PACKAGES_PATH=%WORKSPACE%\CdeMnwPkg;%PACKAGES_PATH%; +set PACKAGES_PATH=%WORKSPACE%\CdeEmuPkg;%PACKAGES_PATH%; + +set EDK_TOOLS_PATH=%WORKSPACE%\edk2\BaseTools +path=%path%;%WORKSPACE%\openssl-1.0.2r-x64_86-win64;%WORKSPACE%; +set NASM_PREFIX=%WORKSPACE%\nasm-2.13.03\ + +rem ###################################################################### +rem ### PYTHONE_HOME +rem ###################################################################### +for /F %%a in ('where python.exe') do set PYTHON_HOME=%%~dpa + +cd %WORKSPACE%\edk2 + +call edksetup.bat Rebuild + +cd %WORKSPACE%\edk2\BaseTools\Source\C +nmake all + +cd %WORKSPACE%\edk2 + +echo. +rem echo For MINNOWBOARD BUILD type: build -a IA32 -a X64 -n 5 -t VS2015x86 -b DEBUG -p PlatformPkgX64.dsc +rem echo For EMULATION BUILD type: build -p EmulatorPkg.dsc -t VS2015x86 -a IA32 +echo For MINNOWBOARD BUILD type: BLD REL / DEB +echo For EMULATION BUILD type: BLD EMU +%COMSPEC% /k echo Welcome, to the jungle... diff --git a/runemu.bat b/runemu.bat new file mode 100644 index 00000000000..d246175a23e --- /dev/null +++ b/runemu.bat @@ -0,0 +1,8 @@ +@echo off +rem +rem Copyright (c) 2019, Kilian Kegel. All rights reserved.
+rem SPDX-License-Identifier: BSD-2-Clause-Patent +rem +pushd %WORKSPACE%\Build\EmulatorIA32\DEBUG_VS2015x86\IA32 +start %WORKSPACE%\Build\EmulatorIA32\DEBUG_VS2015x86\IA32\WinHost.exe +popd \ No newline at end of file diff --git a/todoreminder.md b/todoreminder.md new file mode 100644 index 00000000000..7a70d13aa5b --- /dev/null +++ b/todoreminder.md @@ -0,0 +1,5 @@ +#̶#̶#̶ ̶2̶0̶1̶9̶0̶6̶0̶7̶ +̶*̶ ̶c̶h̶a̶n̶g̶e̶ ̶D̶E̶P̶E̶X̶ ̶f̶o̶r̶ ̶<̶e̶m̶>̶C̶d̶e̶P̶k̶g̶<̶/̶e̶m̶>̶D̶r̶i̶v̶e̶r̶ ̶f̶r̶o̶m̶ ̶g̶C̶d̶e̶C̶o̶m̶m̶a̶n̶d̶L̶i̶n̶e̶P̶r̶o̶t̶o̶c̶o̶l̶G̶u̶i̶d̶ ̶t̶o̶ ̶g̶C̶d̶e̶D̶x̶e̶P̶r̶o̶t̶o̶c̶o̶l̶G̶u̶i̶d̶/̶C̶D̶E̶_̶D̶X̶E̶_̶P̶R̶O̶T̶O̶C̶O̶L̶_̶G̶U̶I̶D̶ ̶ +̶ ̶ ̶s̶i̶n̶c̶e̶ ̶<̶e̶m̶>̶C̶d̶e̶S̶e̶r̶v̶i̶c̶e̶s̶<̶/̶e̶m̶>̶ ̶a̶l̶r̶e̶a̶d̶y̶ ̶d̶e̶p̶e̶n̶d̶s̶ ̶o̶n̶ ̶g̶C̶d̶e̶C̶o̶m̶m̶a̶n̶d̶L̶i̶n̶e̶P̶r̶o̶t̶o̶c̶o̶l̶G̶u̶i̶d̶.̶ + + The sample implementation on the MinnowBoard is okay despite that DEPEX fault.